Why an Rvalue Link Is Included in an Lvalue Link Using a Universal Link

I believe that when the universal reference parameter is matched with the rvalue reference argument, the returned rvalue reference argument is returned. However, my testing shows that the rvalue link turns into an lvalue link with a generic link function template. Why is this so?

#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
T f1(T&&t) {  //<-----this is a universal reference
  cout << "is_lvalue reference:" << is_lvalue_reference<T>::value << endl;
  cout << "is_rvalue reference:" << is_rvalue_reference<T>::value << endl;
  cout << "is_reference:"        << is_reference<T>::value        << endl;
  return t;
}
void f2(int&& t) {
  cout << "f2 is_lvalue reference:" << is_lvalue_reference<decltype(t)>::value << endl;
  cout << "f2 is_rvalue reference:" << is_rvalue_reference<decltype(t)>::value << endl;
  cout << "f2 is_reference:" << is_reference<decltype(t)>::value << endl;
  f1(t);

}

int main()
{
  f2(5);
  return 0;
}

In both GCC and VC ++ 2010, this is the result:

f2 is_lvalue reference:0
f2 is_rvalue reference:1
f2 is_reference:1
is_lvalue reference:1
is_rvalue reference:0
is_reference:1

In other words, the parameter tin f2was a reference to rvalue, but when it was passed to f1, the parameter became an lvalue reference. Should the value of r be kept f1?

+4
source share
3

, rvalue lvalues.

std:: move f2 t f1 rvalueness:

void f2(int&& t) {
    f1(std::move(t));
}

.

+5

f1(t), t. static_cast<decltype(t)>(t) - . decltype(t) f1(t).

t int lvalue. ( , , lvalue, , , &t). "", ​​ , decltype.

f1 lvalue, t int&.

NB. , f1 decltype(t), t, , is_rvalue_reference f1. rvalue t , . f2, f1(std::move(t));, f1 t int decltype(t) f1 is int&&.

+3

++ 11 , f1(t); f2. , , :

  • f2, t l int&& ( int, )
  • f1(t); :

    2.1, t f1 lvalue, lvalue int&& &

    2.2 , int&& & int &. t.

  • Because the parameter is f1declared as T&&, the type of the parameter tin f1is int & &&. Thus, the reversal of collapse occurs a second time to infer the type tas int &.

  • Therefore, T = int &, and the type of the parameter tis equal int &. that is, the parameter tis an l value of typeint &

Any comments?

0
source

Source: https://habr.com/ru/post/1665106/


All Articles