Candag Candag - 3 months ago 11
C++ Question

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?

Answer

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

Comments