【问题标题】:assigning to rvalue: why does this compile?分配给右值:为什么会编译?
【发布时间】:2015-11-18 15:29:08
【问题描述】:

在以下示例中:

class A {
  private: double content;

  public:
  A():content(0) {}

  A operator+(const A& other) {     
    content += other.content;
    return *this;
  }

 void operator=(const A& other) {
       content = other.content;
  }

};

A 是一个 double 的简单包装器,其中 += 运算符已被重载。在以下用途中:

 int main(int argc, char *argv[]) {
    A a, b, c;
    (a+b) = c ; // Why is this operation legal?
}

为什么(a+b) = c会编译?我想知道为什么这个语句是合法的,因为(a+b)的结果必须是rvalue。我没有返回来自operator+ 的引用。

【问题讨论】:

  • 重载的操作符只是函数调用;他们对参数的值类别没有任何特殊限制。由于您没有重新限定赋值运算符重载,因此它接受任何值类别的实例。
  • 能否详细说明
  • 嗯,你不会抱怨(a + b).display() 有效,对吧?

标签: c++ reference lvalue rvalue


【解决方案1】:

(a+b) = c(a+b).operator=(c) 相同。赋值运算符中的右值引用没有特殊规则,它只是遵循通常的函数调用规则。如果你想阻止使用右值调用,你可以添加一个 ref 限定符:

void operator= (const A& other) & {
//                              ^
     content = other.content;
}

这将只允许在左值上调用函数。

【讨论】:

  • 所以,通常 = 作为默认赋值运算符需要在左侧有一个左值(除了 C++11 右值引用),但是当我自己重载 = 时,这个要求就会消失,对吗?
  • @IIIIIIIIIIIIIIIIIIIIIIII 是的。
  • @TartanLlama 实际上没有;类类型的默认operator= 也允许在左侧使用prvalue。是否存在用户提供的过载并没有什么区别。您显然是指在左侧有一个原始类型(不确定 OP 是否也清楚)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多