L和R参考变量

问题描述 投票:1回答:1

我试图理解Rvalue和Lvalue参考变量的基本概念,以及如何将它们作为变量的函数参数相互转换(如果可能),并理解它们所涉及的内存操作-因此,我总结了具有必需的CTor和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();}

但是我无法使用R值参考变量来调用fooRRef功能模板:

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参考变量的概念是什么以及如何使用它们?

c++ c++11 reference c++14 rvalue-reference
1个回答
1
投票

但是我无法使用R值参考变量来调用fooRRef功能模板:

您对typesvalue categories感到困惑。作为一个命名变量,ra是一个左值,因此不能绑定到右值引用。

(重点是我的)

每个C ++表达式(带有其操作数,文字,变量名称等)的特征是两个独立属性:类型值类别

以下表达式是左值表达式:

  • 变量的名称,函数, a template parameter object (since C++20)或数据成员,无论类型如何,例如std::cinstd::endl即使变量的类型是右值引用,由名称组成的表达式是左值表达式;

另一方面,它可以绑定到左值引用,例如

fooLRef<A>(ra); // works

您还可以通过std::move将其明确转换为右值,例如

std::move

右值引用变量的名称为左值,必须为转换为xvalues以绑定到接受的函数重载右值参考参数,这就是为什么移动构造函数和移动赋值运算符通常使用fooRRef<A>(std::move(ra)); // works

© www.soinside.com 2019 - 2024. All rights reserved.