Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template overloading (reference and non reference version)

I have a seemingly simple question that I don't know how to solve.

Imagine the following template method

template<typename T> void Add(T& var);

where the specializations can Add something to a container (sort of). I can pass in POD or more complicated types like strings and that is why I'm passing T as a reference.

The problem with this is that whenever I want to call Add(...) with a result of another method like:

Add(MethodThatReturnsAnInt());

This won't work and a temporary variable is needed to hold the result of MethodThatReturnsAnInt().

Is there any way of overloading Add so that I can have a reference passing and non reference passing version?

template<typename T> void Add(T& var);
template<typename T> void Add(T var);

would std::enable_if be of any use in this situation?

like image 452
André Moreira Avatar asked Aug 01 '16 11:08

André Moreira


2 Answers

If you have a C++11 compiler, you could use a (Universal Reference) forwarding reference:

template<typename T> void Add(T&& var) {}

int MethodThatReturnsAnInt() { return 42; }

int main()
{
    int a = MethodThatReturnsAnInt();

    Add(a);                        // lvalue passed: void Add(int& var) takes lvalue reference  
    Add(MethodThatReturnsAnInt()); // rvalue passed: void Add(int&& var) takes rvalue reference  
}

T&& is not a rvalue reference in this example. In a type-deducing context T&& has a special meaning. T depends on the expression passed to the function Add() as follows:

  • If the expression is an lvalue (eg: a) of type E, then T is deduced to E&.

  • If the expression is an rvalue (eg: value returned by a function) of type E, then T is deduced to E and var will have the type E&&.

like image 108
sergej Avatar answered Oct 19 '22 11:10

sergej


If your compiler does not already support C++11, you will need to update your compiler, and then use a forwarding reference, &&.

like image 2
Sam Varshavchik Avatar answered Oct 19 '22 12:10

Sam Varshavchik