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 -
"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
Post a Comment