I have a template function in the style of:
template <int Exponent> DERIVED_TYPE pow(TYPE const x);
This function is defined in the string structure of the template as a friend function:
template <ARGUMENTS> struct unit { typedef unit<ARGUMENTS> type; .... template <int Exponent> friend constexpr unit_pow_t<type, Exponent> pow(type const x) { ... } };
This is due to the fact that when using a unit value with power, you must change the device along with the value.
When I try to use it without an exponent, I see candidates that the compiler considers to match:
src/model/Tool.cpp:113:3: error: no matching function for call to 'pow' pow(1._m); ^~~ src/model/../units/Units.hpp:2266:46: note: candidate template ignored: couldn't infer template argument 'Exponent' friend constexpr unit_pow_t<type, Exponent> pow(type const x) { ^ /usr/include/math.h:255:8: note: candidate function not viable: requires 2 arguments, but 1 was provided double pow(double, double); ^
So far, everything has been as expected, the template is being viewed, but, of course, you must specify the exhibitor. When I do, something unexpected happens:
src/model/Tool.cpp:113:6: error: comparison between pointer and integer ('double (*)(double, double)' and 'int') pow<3>(1._m); ~~~^~
The compiler sees pow as the address of "double pow (double, double)" and interprets <3 as the goal of comparing the function pointer with an integer. The problem occurs with clang 3.4, 3.6 and GCC 5.2.
My question is: how do I convince the compiler that <3> is a list of template arguments?
UPDATE
I finally managed to create a minimal example, sorry for the incomplete question:
template <int Exp> struct metre { double value; template <int Exponent> friend constexpr metre<Exp * Exponent> pow(metre<Exp> const x) { return {0}; } }; int main() { pow<2>(metre<1>{1}); return 0; };
He doesn't seem to see pow:
targs.cpp:11:2: error: use of undeclared identifier 'pow' pow<2>(metre<1>{1}); ^
If I enable cmath, I have the same diagnostics as before:
targs.cpp:13:5: error: comparison between pointer and integer ('double (*)(double, double)' and 'int') pow<2>(metre<1>{1}); ~~~^~ 1 error generated.
Thus, the presence of "double pow (double, double)" simply masks the problem that the template is not displayed. The question then becomes: why are pow <> () not considered by the compiler?