Rahul Garg
Rahul Garg

Reputation: 61

Template doubt in C++

#include <iostream>
using namespace std;
template<typename T> void test()
{
     cout << "Called from template T";
}
template<int I> void test()
{
     cout << "Called from int";
}
int main()
{
     test<int()>();      
}

In the above snippet test<int()>() calls the first version and gives output

Called from template T

Why doesn't the second version get called?

Upvotes: 6

Views: 300

Answers (4)

tyms
tyms

Reputation: 71

Try:

test<(int())>();

Upvotes: 7

sbi
sbi

Reputation: 224049

I think you wanted the second template to be invoked whenever T is int. John has shown you how to do that, and Benoit has shown you what you need to do in order to actually call the second function.

Your problem is that by trying to specialize test<>() for a specific type (int) using the completely wrong syntax, you have accidentally hit another valid syntactic form. (Kind of bad luck.) That second function template is using a so-called non-type template parameter. For besides types you can use other things as template parameters. Among others (functions, templates) you can also use integral constants, like int. Had you tried to do this with, say, double, the code would have failed to compile.
Your second test<>() template is an overload of the first one which can be used with constant integers. That's why Benoit's test<0>() would compile.

For a full specialization (there is no partial specialization for function templates, there's just overloading; class templates, however, do have partial specialization), you have to always provide an empty template parameter list (template<>) and put the types to specialize for behind the identifier test<int>.

Upvotes: 1

jcoder
jcoder

Reputation: 30035

It's not entirely clear to me what you are trying to achieve with this. But if you wanted to use a different template specialization when you instantiate the template with an int rather than any other type then this is the syntax you need -

  #include <iostream>

  using namespace std;

  template<typename T> void test()
  {
       cout << "Called from template T";
  }

  template<> void test<int>()
  {
       cout << "Called from int";
  }


  int main()
  {
          test<int>(); 

  }

Upvotes: 5

Prasoon Saurav
Prasoon Saurav

Reputation: 92854

As per ISO C++03 (Section 14.3/2)

In a template-argument, an ambiguity between a type-id and an expression is resolved to a type-id. int() is a type-id so the first version gets called.

Upvotes: 11

Related Questions