Переменная L и R - PullRequest
       65

Переменная L и R

1 голос
/ 03 апреля 2020

Я пытаюсь понять основные понятия c ссылочной переменной Rvalue и Lvalue, а также то, как их можно преобразовать друг в друга (если это возможно) в качестве параметра функции в качестве переменных и понять операции с памятью, которые в них задействованы - следовательно, я создал класс с необходимыми CTors и Dtor для понимания создания / уничтожения временного объекта во время операции:

class A
{
public:
   A() {std::cout << "CTor Called" << std::endl;}
   A(const A& a) {std::cout << "Copy CTor Called" << std::endl;}
   A(A&& a) {std::cout << "MOve CTor Called" << std::endl; }
   void operator =(const A& a){std::cout << "operator= Called" << std::endl;}
   ~A() {std::cout << "DTor Called" << std::endl;}
   void Show(){std::cout << "Show Called" << std::endl;}
};

Сначала я могу создать ссылочные переменные значения R & L:

    A a;
    A& a1 = a;
    const A& a2 = A(); // Lvalue using Rvalue
   //But I am unable to create R refererence variable using an L value variable
    A&& ra = a; // Does not work
    A&& ra = A(); // works

Таким образом, справочные переменные значения R могут создаваться только значениями R в отличие от значений L, которые могут быть получены с использованием значения R

Теперь я записал шаблоны ниже:

template <class T> void fooNoRef(T tmp){tmp.Show();}
template <class T> void fooLRef(T& tmp){tmp.Show();}
template <class T> void fooRRef(T&& tmp){tmp.Show();}

Но я не могу вызвать fooRRef шаблон функции, используя ссылочную переменную значения R:

int main()
{
    A a;
    A& a1 = a;
    const A& a2 = A();
    A&& ra = A();
    std::cout << "Calling fooNoRef Template Function" << std::endl;
    fooNoRef<A>(a);
    std::cout << "Calling fooLRef Template Function" << std::endl;
    fooLRef<A>(a);
    std::cout << "Calling fooRRef Template Function With Lvalue" << std::endl;
    fooRRef<A>(ra); // Does not works??
    fooRRef<A>(A());
}

Так, каково понятие ссылочной переменной R и L и как их использовать?

1 Ответ

1 голос
/ 03 апреля 2020

Но я не могу вызвать fooRRef шаблон функции с использованием ссылочной переменной значения R:

Вы путаете с типами и значения категории . В качестве именованной переменной ra является lvalue, и его нельзя привязать к rvalue-reference.

(выделено мной)

Каждое выражение C ++ (оператор с его операндами, литералом, именем переменной и т. Д. c.) Характеризуется двумя независимыми свойства: тип и категория значения .

Следующие выражения являются выражениями lvalue:

  • имя переменная, функция , a template parameter object (since C++20) или член данных, независимо от типа, например std::cin или std::endl. Даже если тип переменной является ссылкой на rvalue, выражение, состоящее из ее имени, является выражением lvalue ;

С другой стороны, оно может быть связано с lvalue- ссылка, например,

fooLRef<A>(ra); // works

Вы также можете явно преобразовать ее в rvalue с помощью std::move, например,

fooRRef<A>(std::move(ra)); // works

Имена переменных ссылки на rvalue lvalues ​​и должны быть преобразованы в xvalue для привязки к перегрузкам функций, которые принимают опорные параметры rvalue, поэтому конструкторы перемещения и операторы присваивания перемещения обычно используют std::move:

...