Search code examples
c++c++11type-traits

reference-ness doesn't stick with type in a template function


Consider the following short program:

#include <type_traits>
#include <iostream>
using namespace std;

template <typename T>
void fn( T t ) {
    cout << "T is reference: " <<
        boolalpha << is_reference<T>::value << endl;
}


int main( void ) {
    int x = 0;
    int& r = x;
    fn( r );
}

Running this program, I'm getting: T is reference: false.
Would would be the explanation?


Solution

  • The C++ 2003 template type deduction tries to find a matching argument type. If you want to take a reference as argument you need to say so and possibly overload the template appropriately. Changing referenceness would actually generally not be what you want (although you could remove the reference part of the deduced type). Generally, the concepts implemented by a reference type are quite different from those used for values. Also note that r is just another name for x for the purpose of type deduction and overload resolution.

    In C++ 2011 you can ask the compiler to retain a bit more type information: when deducing the type in a template using rvalue reference notation (i.e. T&& for a template argument T), the type will be deduced to be a reference with cv-qualuiiers applied appropriately for lvalues and a value type for non-lvalues. That is the deduced type essentially depends on whether the argument is a temporary object (or at least is made to look like one).