Modern (Effective) C++ - Difference between RValue references and Universal references

This article is inspired from Item 24 of Effective Modern C++ by Scott Meyers.

Even though Rvalue references, and universal references have the same syntax(&&), they are quite different.


void(int&& xyz);
int&& x = funcA();
view raw rvalue_ref.cpp hosted with ❤ by GitHub
In the above examples, the types are known (not deduced). They are Rvalue references


template<typename T>
funcB(T&& x);
auto&& x = y;
funcC = [](auto&& zy, auto&& mx)
{
cout << zy << ' ' << mx;
}
In the above examples, the types are deduced (using type deduction rules). These are universal references.Universal references can accept both Rvalues and Lvalues, but they must be initialized.
We will now examine some special cases which looks like universal references, but are Rvalue references.


// might look like universal references, but it's not
template<typename T>
void funcA(vector<T>&& vec)
{
}
template<typename T>
class Car
{
void drive(T&& x)
{
}
template<typename U>
void spin(const U&& y)
{
}
};
void funcB(const T&& x);
void funcC(volatile T&& y);


In these examples -
  • The T in vector<T>  of funcA is known, when the vector gets instantiated. Hence T is not type deduced.
  • In the drive function, T is known when the class Car gets instantiated. Hence T for drive is not type deduced.
  • In the spin function U is const qualified. Hence it is not universal reference.
  • In funcB, T is const qualified. Hence it is not universal reference.
  • In funcC, T is volatile qualified. Hence it is not universal reference.
Hence in all these cases the parameters are deduced to Rvalue references. If we try to pass a Lvalue to these functions, they will fail to compile.
Modern (Effective) C++ - Difference between RValue references and Universal references Modern (Effective) C++ - Difference between RValue references and Universal references Reviewed by zeroingTheDot on February 14, 2018 Rating: 5

No comments:

Powered by Blogger.