赋值的右操作数是否总是转换为右值?
Is the right operand of an assignment always converted to an rvalue?
我想澄清一下这个特殊案例:
class Test
{
Test& operator=(const Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
b = a; //Is "a" converted to an rvalue?
"a" 是左值,但它现在是赋值的右手操作数。这是否意味着它被转换为右值?
此代码无法编译:
class Test
{
Test& operator=(Test&& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //Error
但是这个确实如此:
class Test
{
Test& operator=(Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //OK
既然左值引用不能绑定到右值,是否意味着这里没有发生转换?如果是这样,什么时候会发生隐式左值到右值转换? (原始类型的 operator+ 除外)
这是左值,b = a;
调用复制运算符
class Test
{
Test& operator=(const Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
b = a; //Is "a" converted to an rvalue?
错误,因为你的复制构造函数和复制运算符不是由编译器生成的,因为声明了移动运算符
class Test
{
Test& operator=(Test&& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //Error
如果你想得到右值你可以这样写:
Test a;
Test b;
a = Test(); //Uses move operator
"a" is an lvalue, however it is now the righthand operand of the assignment. Does it mean it gets converted to an rvalue?
简而言之,是的。在 C++ 标准的所有版本和草案中,其中一种标准转换称为 "lvalue-to-rvalue" 转换。
适用于你描述的第一种情况。
Since an lvalue reference cannot bind to an rvalue, does it mean a conversion is not happening here? If that is the case, when does an implicit lvalue-to-rvalue conversion happen? (Other than the case of the operator+ with primitive types)
在第二种情况下,您有 declared/defined 一个接受右值引用的 operator=(Test &&)
,它抑制了 operator=(const Test &)
的生成。在 C++11 及更高版本中,在没有 operator=(Test &)
或 operator(const Test &)
之一的情况下声明 operator=(Test &&)
会阻止在右侧使用左值(如您的示例中的 a = b
) .
这间接意味着在这种情况下不使用左值到右值的转换。
您的情况没有左值到右值的转换(忽略 operator=
定义中的代码)。
此处您使用了重载运算符,并且根据 [expr.pre]/2、
Overloaded operators obey the rules for syntax and evaluation order specified in [expr.compound], but the requirements of operand type and value category are replaced by the rules for function call.
所以它不需要右操作数是纯右值,因此没有左值到右值的转换。
我想澄清一下这个特殊案例:
class Test
{
Test& operator=(const Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
b = a; //Is "a" converted to an rvalue?
"a" 是左值,但它现在是赋值的右手操作数。这是否意味着它被转换为右值?
此代码无法编译:
class Test
{
Test& operator=(Test&& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //Error
但是这个确实如此:
class Test
{
Test& operator=(Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //OK
既然左值引用不能绑定到右值,是否意味着这里没有发生转换?如果是这样,什么时候会发生隐式左值到右值转换? (原始类型的 operator+ 除外)
这是左值,b = a;
调用复制运算符
class Test
{
Test& operator=(const Test& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
b = a; //Is "a" converted to an rvalue?
错误,因为你的复制构造函数和复制运算符不是由编译器生成的,因为声明了移动运算符
class Test
{
Test& operator=(Test&& copy)
{
...
}
Test() = default;
}
Test a;
Test b;
a = b; //Error
如果你想得到右值你可以这样写:
Test a;
Test b;
a = Test(); //Uses move operator
"a" is an lvalue, however it is now the righthand operand of the assignment. Does it mean it gets converted to an rvalue?
简而言之,是的。在 C++ 标准的所有版本和草案中,其中一种标准转换称为 "lvalue-to-rvalue" 转换。
适用于你描述的第一种情况。
Since an lvalue reference cannot bind to an rvalue, does it mean a conversion is not happening here? If that is the case, when does an implicit lvalue-to-rvalue conversion happen? (Other than the case of the operator+ with primitive types)
在第二种情况下,您有 declared/defined 一个接受右值引用的 operator=(Test &&)
,它抑制了 operator=(const Test &)
的生成。在 C++11 及更高版本中,在没有 operator=(Test &)
或 operator(const Test &)
之一的情况下声明 operator=(Test &&)
会阻止在右侧使用左值(如您的示例中的 a = b
) .
这间接意味着在这种情况下不使用左值到右值的转换。
您的情况没有左值到右值的转换(忽略 operator=
定义中的代码)。
此处您使用了重载运算符,并且根据 [expr.pre]/2、
Overloaded operators obey the rules for syntax and evaluation order specified in [expr.compound], but the requirements of operand type and value category are replaced by the rules for function call.
所以它不需要右操作数是纯右值,因此没有左值到右值的转换。