左侧的右值

时间:2016-01-17 06:13:45

标签: c++ c++11 rvalue lvalue-to-rvalue

为什么这段代码会编译?我认为ctor返回的rvalues不在内存中,因此不能用作左值。

#include <iostream>
#include <vector>

class Y {
public :
    explicit Y(size_t num = 0)
    : m_resource {std::vector<int>(num)}
    {
    }

    std::vector<int> m_resource;
};

int main(int argc, const char * argv[]) {
    Y(1) = Y(0); // WHAT?!?
    return 0;
}

2 个答案:

答案 0 :(得分:7)

根据见12.8 [class.copy]第18段,将合成赋值运算符声明为其中之一(如果它可以合成并且未声明为已删除):

  • Y& Y::operator=(Y const&)
  • Y& Y::operator=(Y&)()

也就是说,与未使用ref-qualifiers特别声明的任何其他成员函数一样,它适用于rvalues。

如果你想阻止作业左侧的临时对象,你需要相应地声明它:

class Y {
public :
    explicit Y(std::size_t num = 0);
    Y& operator= (Y const&) & = default;
};

标准在&之前为= default使用名称​​ ref-qualifier 。相关提案为N2439。我不知道 ref-qualifiers 的描述在哪里。 this question有一些信息。

答案 1 :(得分:1)

不确定您在哪里获得了特定的经验法则。如果有的话,根据经验(来自Scott Meyers):如果它有名字,那就是左值。

在这种情况下,您将创建一个临时对象并将其传递给赋值方法/函数。这没有问题。事实上,这样做甚至可能有意义,如

// Applies foo to a copy, not the original.
(Y(1) = y).foo()

确实Y(*)这里没有名字,因此它们是rvalues。