Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templates specialization

I have the following set of templates:

//1  
template< typename T > void funcT( T arg )  
{
    std::cout<<"1: template< typename T > void funcT( T arg )";  
}  
//2  
template< typename T > void funcT( T * arg )  
{
    std::cout<<"2: template< typename T > void funcT( T * arg )";  
}  
//3  
template<> void funcT< int >( int arg )  
{  
    std::cout<<"3: template<> void funcT< int >( int arg )";  
}  
//4  
template<> void funcT< int * >( int * arg )  
{  
    std::cout<<"4: template<> void funcT< int *>( int * arg )";  
}  

//...  

int x1 = 10;  
funcT( x1 );  
funcT( &x1 );  

Can someone please explain why funcT( x1 ); calls function #3 and funcT( &x1 ); calls function #2 but not #4 as expected?
I have already read this article http://www.gotw.ca/publications/mill17.htm which says that "overload resolution ignores specializations and operates on the base function templates only". But according to this logic funcT( x1 ); should call function #1, not #3. I am confused.

like image 982
Dimon Avatar asked Feb 03 '10 21:02

Dimon


1 Answers

Functions #3 and #4 are specializations of #1, not of #1 and #2 respectively.

This means that your compiler will choose between #1 and #2 first. When it has selected #1 to be the best fit for funcT(x1), it then selects the specialization, #3. For funcT(&x1), it chooses #2 as the best fit and finds no specializations.

By writing #4 as

template<> void funcT<>( int * arg )

it becomes a specialization of #2 and you'll get the expected result that #4 is called for funcT(&x1).

Another option would be to simply write

void funcT(int *arg)

since regular functions will always be chosen instead of templated versions if they match.

like image 63
villintehaspam Avatar answered Nov 18 '22 05:11

villintehaspam