为什么可以分配给类类型的右值?

问题描述 投票:0回答:2

为什么这段代码可以编译?我认为 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;
}
c++ c++11 language-lawyer rvalue lvalue-to-rvalue
2个回答
11
投票

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

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

也就是说,就像任何其他未使用 ref-qualifiers 专门声明的成员函数一样,它适用于右值。

如果你想防止在赋值的左侧出现临时对象,你需要相应地声明它:

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

标准使用名称 ref-qualifier 来表示

&
之前的
= default
。相关提案是N2439。我不知道哪里有关于 ref-qualifiers 的详细描述。 这个问题有一些信息。


1
投票

不确定您从哪里得到这个特定的经验法则。如果有的话,经验法则是(来自 Scott Meyers):如果它有名称,它就是一个左值。

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

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

确实,

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

© www.soinside.com 2019 - 2024. All rights reserved.