tags:

views:

202

answers:

4
  #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?

+14  A: 

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.

Prasoon Saurav
Technically correct, though you could mention that using test<2>() will call the second one, since `2` resolves to `int`.
Zooba
+8  A: 

Try:

test<(int())>();
tyms
@sbi no it's a good hint, although misses some explanation. The parens around `int()` make it an expression of type `int`.
Johannes Schaub - litb
@Johannes: Indeed. _I_ should have tried before I blurted out... @tyms: Sorry. I removed my down-vote. (But I won't up-vote because this doesn't explain why yours would work.)
sbi
+4  A: 

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>(); 

  }
John Burton
`+1` for the only answer here that shows how to do what, IMO, Rahul actually wanted to do - define a specialization.
sbi
A bit OT: In general I would say that method specialization is discouraged. Herb Sutter tells the story better than me: http://www.gotw.ca/publications/mill17.htm
FuleSnabel
@FuleSnabel: I avoid using overloading instead of the missing function template _partial_ specialization, but I've always used _full_ specialization.
sbi
+1  A: 

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>.

sbi
While I have been doing a lot of things wrong on this whole thread, unless you point out to what's wrong with my answer, it's not fair to down-vote it.
sbi