赋值的右操作数是否总是转换为右值?

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.

所以它不需要右操作数是纯右值,因此没有左值到右值的转换。