【问题标题】:rvalue on the left side左侧的右值
【发布时间】:2016-04-22 12:00:06
【问题描述】:

为什么要编译这段代码?我认为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;
}

【问题讨论】:

  • 可以在任何对象上调用成员函数operator=。您的代码与Y(1).operator=(Y(0)); 相同

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


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 我试过了,效果很好。在 '= default' 之前调用的 '&' 是什么?我在哪里可以了解更多关于这种不熟悉的语法的信息?
  • @JohnDifool here is another thread on the topic。如果您在 stackoverflow 中搜索“ref qualifier”,您应该会发现更多
  • @JohnDifool:我的回答提到了“引用限定符”,但我同意这个非正式的名称并没有那么有用,我已经相应地更改了答案。
  • 我在 C++ Primer book 中找到了这个:“引用限定符:用于指示非静态成员函数可以在左值或右值上调用的符号。限定符 & 或 && 遵循参数列表或 const 限定符(如果有)。由 & 限定的函数只能在左值上调用;由 && 限定的函数只能在右值上调用。我可能需要做一些挖掘才能理解最后一部分的含义。
  • 在多读多想之后,如果可以的话,我还有一个问题:您建议添加“Y& operator= (Y const&) & = default;”有效,但不等于说您需要默认的“综合”行为吗?换句话说,为什么它可以与“默认”一起使用,而我认为它应该是“删除”?
【解决方案2】:

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

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

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

Y(*) 确实在此处没有名称,因此它们是右值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多