开发者

Specializing function template for reference types

开发者 https://www.devze.com 2023-02-04 04:10 出处:网络
Why is the output of this code : #include <iostream> template<typename T> void f(T param) {

Why is the output of this code :

#include <iostream>  
template<typename T> void f(T param) 
{ 
   std::cout << "General" << std::endl ; 
} 
template<> void f(int& param) 
{ 
   std::cout << "int&" << std::endl ; 
}  

int main() 
{   
  float x ;  f开发者_如何学编程 (x) ;   
  int y ; f (y) ;   
  int& z = y ; f (z) ; 
}  

is

General

General

General

The third one is surprizing because the function was specialized exactly for int&

Edit : I know that overloading might be a proper solution. I just want to learn the logic behind it.


The type of both the expression y and the expression z is int. A reference appearing in an expression won't keep reference type. Instead, the type of the expression will be the referenced type, with the expression being an lvalue.

So in both cases, T is deduced to int, and thus the explicit specialization is not used at all.

What's important to note (other than that you should really use overloading, as another guy said), is that you have a non-reference function parameter in your template. Before any deduction of T against the argument type is done, the argument type will be converted from arrays to a pointer to their first element (for functions, arguments will be converted to function pointers). So a function template with a non-reference function parameter doesn't allow for accurate deduction anyway.


A reference is just an alias, not a type. So when you call f(z), it matches the first version with T=int, which is a better option that T=int&. If you change T to T&, then both int and int& arguments will call the second version.


I know it is not answer but, IMHO you can try this, with a trait like approach in a struct:

template<typename T>
struct value_traits
{
    static void print(){std::cout << "General" << std::endl ;} 
};

template<>
struct value_traits<const long>
{
    static void print(){std::cout << "const long" << std::endl ;} 
};

template<>
struct value_traits<std::vector<unsigned char> >
{
    static void print(){std::cout << "std::vector<unsigned char>" << std::endl ; }
};

template<>
struct value_traits<const int>
{
       static void print(){std::cout << "const int" << std::endl ;} 
};
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号