2

I accidentally made a mistake coding a template function specialization, and the resulting construct passed compilation with VS17. ( The third construct in the included code below )

Is this a valid construct? How would I call this function?

template <class T> void tempfunc(T t)
{
    cout << "Generic Template Version\n";
}

template <>
void tempfunc<int>(int i) {
    cout << "Template Specialization Version\n";
}

template <int> void tempfunc(int i)
{
    cout << "Coding Mistake Version\n";
}

I have not been able to call the third construct.

Gonen I
  • 5,576
  • 1
  • 29
  • 60

2 Answers2

6

Yes, it's a valid construct. It's a template overload, that is templated on a non-type template parameter of type int.

You can call it like this:

tempfunc<42>(42);

Note that calls without the template syntax will still call the versions that are templated on a type parameter:

tempfunc(42);   // calls specialization
tempfunc(true); // calls primary 

Here's a demo

cigien
  • 57,834
  • 11
  • 73
  • 112
  • 1
    @cigien Thanks for the explanation. While I was familiar with non-type template parameters, I don't think I had seen an example with the parameter name omitted. – Gonen I Oct 01 '20 at 19:41
  • @GonenI: I never have either. I'm struggling to think of a use for it – Mooing Duck Oct 01 '20 at 19:43
  • 1
    @MooingDuck right here: https://stackoverflow.com/questions/59824884/whats-the-point-of-unnamed-non-type-template-parameters – Gonen I Oct 01 '20 at 19:44
3

template parameters are of two kinds - type parameters and non-type parameters.

When you use

template <class T> void tempfunc(T t) { ... }

the template parameter is a type parameter. To use such a template, the type has to either deduced or explicitly provided.

When you use

template <int> void tempfunc(int i) { ... }

the template parameter is a non-type parameter. As far as I know, the value of a non-type parameter cannot be deduced. It has to be explicitly provided.

The last template uses a non-type paramter. The value with which it can be called has to be of type int. Example invocations:

tempfunc<0>(20);
tempfunc<999>(34);
R Sahu
  • 204,454
  • 14
  • 159
  • 270