Ambigous function call with template

Hello,

I have a piece of code that works perfectly with recent versions of g++ but
fails to compile with clang++. I try to understand why.

ScalarOperations.h:

    template<typename Type>
      typename utils::EnableIf<(not IsVector<Type>::value),
      bool
    >::Type smallerEquals (
      Type lhs,
      Type rhs,
      Type tolerance = NUMERICAL_ZERO_DIFFERENCE);

ScalarOperations.cpph:

template<typename Type>
  inline
  typename utils::EnableIf<not IsVector<Type>::value,
  bool

::Type smallerEquals (

  Type lhs,
  Type rhs,
  Type tolerance
) {
  return lhs - rhs <= tolerance;
}

this is called from ScalarTest.cpp like that:

#include "code.h"

double a = 1.0;
double b = 2.0;
double eps = 1e-14;
validate (smallerEquals(a, b, eps));

That fails with:

clang++ -o build/debug/tarch/la/tests/ScalarTest.o -c -fPIC -g3 -O0 -DDebug
-DAsserts -Isrc -Isrc -I/usr/include/openmpi -I/usr/include -
I/usr/include/python2.7 -I/usr/include/python2.7/numpy
src/tarch/la/tests/ScalarTest.cpp

src/tarch/la/tests/ScalarTest.cpp:53:13: error: call to 'smallerEquals' is
ambiguous
  validate (smallerEquals(a, b, eps));
            ^~~~~~~~~~~~~
src/tarch/tests/TestMacros.h:45:37: note: expanded from macro 'validate'
#define validate(booleanExpr) if (!(booleanExpr)) { \
                                    ^
src/tarch/la/ScalarOperations.h:77:13: note: candidate function [with Type =
double]
    >::Type smallerEquals (
            ^
src/tarch/la/ScalarOperations.cpph:79:9: note: candidate function [with Type
= double]

::Type smallerEquals (

        ^

Lines 77 resp. 79 are the lines I posted above. If I delete the code in the
CPPH file it compiles fine but fails at linking (of course).

What is the problem here?

Thanks,
Florian

Florian Lindner wrote:

Hello,

I have a piece of code that works perfectly with recent versions of g++
but fails to compile with clang++. I try to understand why.

ScalarOperations.h:

    template<typename Type>
      typename utils::EnableIf<(not IsVector<Type>::value),
      bool
    >::Type smallerEquals (
      Type lhs,
      Type rhs,
      Type tolerance = NUMERICAL_ZERO_DIFFERENCE);

ScalarOperations.cpph:

template<typename Type>
  inline
  typename utils::EnableIf<not IsVector<Type>::value,
  bool

::Type smallerEquals (

  Type lhs,
  Type rhs,
  Type tolerance
) {
  return lhs - rhs <= tolerance;
}

this is called from ScalarTest.cpp like that:

#include "code.h"

double a = 1.0;
double b = 2.0;
double eps = 1e-14;
validate (smallerEquals(a, b, eps));

Amendment: I have a identical function "smaller" (just the operator is not
<= but <) which is called before smallerEquals and does not fail.

Thanks!
Florian