9

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

#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;
}
4

2 回答 2

8

根据见 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;
};

该标准在. _ 相关提案为N2439我不知道ref-qualifiers哪里有很好的描述。这个问题有一些信息。&= default

于 2016-01-17T06:29:16.303 回答
1

不知道你从哪里得到那个特定的经验法则。如果有的话,经验法则是(来自 Scott Meyers):如果它有名字,它就是一个左值。

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

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

不过,这里确实Y(*)没有名称,因此它们是右值。

于 2016-01-17T06:29:04.727 回答