2

I'm trying to do this template instantiation but it's not working. I'm getting the errors:

prog.cpp:7:15: error: template-id 'f<const A&, A()>' for 'void f()' does not match any template declaration

template <class T, T> void f() {}

struct A {};

template void f<const A &, A()>();

int main() {}

This is weird, because when I do it in main it works:

int main() {
    const A &a = A(); // no error
}

So why doesn't it work in the template line?

Me myself and I
  • 3,990
  • 1
  • 23
  • 47

2 Answers2

2

A template argument cannot be a temporary object. Only primitive types which can reasonably be compared for exact equality may be template non-type arguments. This includes

  • integers,
  • enumerators, and
  • pointers to objects with extern linkage.

But

  • floating-point numbers aren't allowed because they can be very close yet not equal
  • static objects might have the same name but different locations in different files, which would make the template-id confusingly resolve to different instantiations with the same name in different files
  • same goes for string literals
  • temporary objects don't have consistent addresses so you can't pass a pointer to one
  • the value of a temporary object as you passed, which can't even be tested for equality, would never let the language match one template instantiation to another!

(As Pubby notes, A() is actually interpreted as the type of a function with no parameters returning A. So the compiler is just failing to find a template declaration taking two type parameters.)

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
2

Possible duplicate of Non-type template parameters

These are the rules of template non type parameters

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

  • integral or enumeration type,
  • pointer to object or pointer to function,
  • lvalue reference to object or lvalue reference to function,
  • pointer to member,
  • std::nullptr_t.

What you are passing is an RValue (temporary object, etc which cannot be assigned to), which does not fall under any of these possibilities.

edit:

It appears that it is infact being interpreted as a function type, but your template signature expects a non type parameter of type A (exactly a const A&)

Community
  • 1
  • 1
Karthik T
  • 31,456
  • 5
  • 68
  • 87