struct A {};
A f1()
{
return A();
}
int f2()
{
return int();
}
int main()
{
f1() = A(); // OK
f2() = int(); // error C2106: '=' : left operand must be l-value
}
为什么失败f1() = A();
时正常?f2() = int();
struct A {};
A f1()
{
return A();
}
int f2()
{
return int();
}
int main()
{
f1() = A(); // OK
f2() = int(); // error C2106: '=' : left operand must be l-value
}
为什么失败f1() = A();
时正常?f2() = int();
f1()
返回 的实例A
。由于您没有覆盖复制/移动赋值运算符,编译器会为您生成一个。您实际上是在调用成员函数:
f1() = A(); // calls A& operator=(A&&)
第二个不起作用,因为int
不是类类型。
函数 f1 返回一个右值,它可能成为一个 xvalue(一个“eXpiring”值)。函数 f2 返回一个内置类型,它是一个右值变成一个纯右值(“纯”右值)。
从 3.10 [左值和右值]
— 一个 xvalue(一个“eXpiring”值)也指一个对象,通常接近其生命周期的末尾(例如,它的资源可能会被移动)。xvalue 是某些涉及右值引用的表达式的结果 (8.3.2)。
因此,由于隐式移动操作,A 的分配变得有效。
将 A 更改为:
struct A {
A() {}
A(A&&) = delete;
A& operator = (const A&) { return *this; }
};
产生:错误:使用已删除的函数 'A::A(A&&)' 与 g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2