我试图理解Rvalue和Lvalue参考变量的基本概念,以及如何将它们作为函数参数或作为变量相互转换(如果可能的话(,并理解其中涉及的内存操作-因此,我创建了一个具有所需CTR和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参考变量的概念是什么?如何使用它们?
但我无法使用R值引用变量调用
fooRRef
函数模板
您混淆了类型和值类别。作为一个命名变量,ra
是一个左值,因此不能绑定到右值引用。
(重点矿井(
每个C++表达式(一个带操作数的运算符、一个文本、一个变量名等(的特征是两个独立的属性:类型和值类别。
以下表达式是左值表达式:
- 变量、函数
, a template parameter object (since C++20)
或数据成员的名称,与类型无关,例如std::cin
或CCD_ 6即使变量的类型是右值引用由其名称组成的表达式是一个左值表达式
另一方面,它可以绑定到左值引用,例如
fooLRef<A>(ra); // works
您也可以通过std::move
显式地将其转换为右值,例如
fooRRef<A>(std::move(ra)); // works
右值引用变量的名称是左值,并且必须是转换为要绑定到接受的函数重载的x值rvalue引用参数,这就是为什么要移动构造函数和move赋值运算符通常使用
std::move
: