A()= A() - 为什么要编译?

scd*_*dmb 84 c++

class A {};

int main() {
 A() = A();
 return 0; 
}
Run Code Online (Sandbox Code Playgroud)

为什么这段代码会编译?不应该有一些错误,在赋值运算符的左侧应该放置左值?是A()左值?g ++ 4.7版本

Mik*_*our 87

对于内置类型,你是正确的:内置赋值运算符需要在左侧有一个可修改的左值.

但是,这不是使用内置运算符,而是由类隐式声明的重载.这是一个成员函数,相当于

A().operator=(A());
Run Code Online (Sandbox Code Playgroud)

并且可以在rvalues上调用成员函数.

  • @Named:不,它的分配不是初始化. (13认同)
  • 是不是复制初始化? (7认同)
  • @ paul23`A()`不调用`operator()`,它构造一个类型为`A`的对象. (3认同)
  • 它不能是初始化,因为没有声明. (3认同)

R. *_*des 32

如果你真的想要,你可以使它不能用C++ 11编译:

class A {
    template <typename T>
    void operator=(T&&) && = delete; // no op= for rvalues

    // generate other special members normally
    A() = default;
    A(A const&) = default;
    A(A&&) = default;
    ~A() = default;
    // op= only for lvalues
    A& operator=(A&&) & = default;
    A& operator=(A const&) & = default;
};

int main() {
 A() = A(); // error
 return 0; 
}
Run Code Online (Sandbox Code Playgroud)

(实例)

请注意各种表单声明结尾处的&&&(也称为ref-qualifiers)operator=.这使得分别为左值和右值选择这些声明.但是,rvalue版本在通过重载决策选择时会导致程序格式错误,因为它已被删除.

但是,默认生成的operator =没有任何ref-qualifier,这意味着可以为lvalues和rvalues调用它; 这就是问题中的代码编译的原因,即使它A()是一个右值.