4

Consider the following code

template <typename T, T one>
T exponentiel(T val, unsigned n) {
    T result = one;
    unsigned i;
    for(i = 0; i < n; ++i)
        result = result * val;

    return result;
}

int main(void) {

    double d = exponentiel<double,1.0>(2.0f,3);

    cout << d << endl;

    return 0;
}

The compiler tells me this no matching function for call to 'exponentiel(float, int)'

Why?

What's strange is that exponentiel works with int.

Justin
  • 41
  • 2

1 Answers1

10

The problem is with the T one and the 1.0 in the template argument list.

You can't have a nontype template parameter of a floating point type and you can't pass a floating point value as a template argument. It's just not allowed (to the best of my knowledge, there's no really good reason why it's not allowed).

g++'s error message here is rather unhelpful. Visual C++ 2010 reports the following on the line where the template is used in main:

error C2993: 'double' : illegal type for non-type template parameter 'one'

Comeau Online reports:

line 13: error: expression must have integral or enum type
    double d = exponentiel<double,1.0>(2.0f,3);
                                  ^

line 2: error: floating-point template parameter is nonstandard
    template <typename T, T one>
                          ^
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    +1. And to go further, the specific error comes up because as James said the template function instantiation you give is invalid. Therefore, the function you're trying to call is never brought into existence. Therefore, there is no matching function for the call. – Lightness Races in Orbit Mar 11 '11 at 01:08
  • "no really good reason why [float parameters] not allowed" with simplistic compiler implementation, epsilon errors result in many template instantiations for what seems superficially like one value. Specialisations might fail to terminate recursion as expected. Even with the same compiler version, these things might be CPU model dependent, CPU dependent etc. - making it hard to use libraries and objects compiled on another machine. Walter Bright allows it in D; the C++ community's much less resilient against post-facto tweaks. Are these your "not good" reasons? What are your thoughts? – Tony Delroy Mar 11 '11 at 01:47
  • @Tony: I reject outright the notion of a simplistic C++ compiler implementation :-) A conforming implementation already has to be able to perform floating point computations in constant expressions. I don't think it's correct to say that the C++ community doesn't like tweaks; certainly _breaking tweaks_ are not liked, but in general, I think people want the language to improve. – James McNellis Mar 11 '11 at 03:05
  • Vandevoorde and Josuttis state in _C++ Templates: The Complete Guide_, "Not being able to use floating-point literals as template arguments has historical reasons. Because there are no serious technical challenges, this may be supported in future versions of C++" (page 40). [Note that they are not supported in C++0x.] – James McNellis Mar 11 '11 at 03:06
  • 1
    I see there's discussion at http://stackoverflow.com/questions/3800867/templatefloating-point-non-type - not much to add. Cheers. – Tony Delroy Mar 11 '11 at 03:22