Rvalue references vs Universal references

Whenever we see "T&&" it seems reasonable to assume that we are referring to "rvalue reference", but it's not.

"T&&" has two different meanings -
  • rvalue reference
  • universal reference.
For instance, below all are rvalue references because the types are known and not deduced.

void fun(Base&& aObj); // rvalue reference
Base&& a = Base();            // rvalue reference

Universal references below in which the type is deduced. The most common is function template and auto declarations.

template<typename T>
void f(T&& param);     // param is being deduced, a universal reference

auto&& obj2 = obj1;   // obj2 is a universal reference

If we look at "T&&" without type deduction, it;s an rvalue reference.

Universal reference can accept both rvalue and lvalue references, but they must be initialized. 
  • If the initializer is rvalue, the universal reference correspnds to rvalue reference.
  • If the initializer is lvalue, the universal reference corresponds to lvaue reference.
For instance:

template<typename T>
void f(T&& arg);   // arg is a universal reference.

A aObj;
f(aObj); // lvalue passed to f - arg type is A& - lvalue reference

f(std::move(aObj));   // rvalue passed to f, arg type is A&& - rvalue reference.

universal reference must be precisely "T&&".

Let's see few more examples-
  • In the below example - the arg is deduced when fun is invoked, but the arg type is not "T&&", it is "std::vector<T>&&". 
template<typename T>
void fun(std::vector<T>&& arg). // arg is an rvalue reference. 
  • In the below example, the presence of "const" qualifier will disqualify a reference from being universal. 
void fun(T&& x);
  • If we are in template, "T&&" doesn't guarantee to be a universal reference. For instance, the addObject member function of "ObjectFactory" below has the right form for a univesal reference, but the type is not deduced while calling addObject, because the type is specified during instantiation of the ObjectFactory class.
template<typename T>
class ObjectFactory
{
      public:
            void addObject(T&& x)
            {
            }
};

Comments

Popular posts from this blog

C++ Guidelines for Multithreaded System

Signalling System #7(SS7) Protocol.

std::shared_ptr