需要一些关于r值概念的帮助

时间:2013-07-19 18:13:16

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

当我尝试编译以下程序时,我得到一个有意义的l值错误。 错误是:错误C2106:'=':左操作数必须是l值

代码:

int main() 
{
    int a,b,c,d;
    b+c=d;
    return 0;
 }

但是当我用我自己的结构替换整数时,下面的代码工作得非常好

struct MyStruct
{
    int val;
    MyStruct(){}
};

MyStruct operator+(MyStruct& s1, MyStruct& s2)
{
    MyStruct temp;
    return temp;
}

int main() 
{

    MyStruct a,b,c,d;
    b+c=d;
    return 0;
}

为什么第二个代码会编译? 我知道我可以从运算符+返回const。但是第二个例子中的b + c不是rvalue吗?那它怎么编译

2 个答案:

答案 0 :(得分:2)

Cory Klein已经解释了here代码编译的原因。

我只想补充一点,如果您希望MyStruct表现为int(以及其他内置类型),请将此行添加到MyStruct

MyStruct& operator =(const MyStruct&) && = delete;

这告诉编译器每次在operator =()对象上调用MyStruct是一个rvalue(感谢 ref-qualifier &&)代码不应该有效,因为operator =()不存在(= delete;)。实际上,GCC 4.8.1引出了以下内容:

  
    

错误:使用已删除的功能'MyStruct& MyStruct :: operator =(const MyStruct&)&&'

b+c=d;
   ^
  

更新:按Casey发表评论(非常感谢)。

将上面的行添加到MyStruct有一个问题。它还可以防止赋值给左值。也就是说,下面的行也变得非法:

b = c;

如果你想禁用rvalue的赋值,但仍允许赋值给左值,那么请将此值添加到MyStruct

,而不是上面的行。
MyStruct& operator =(const MyStruct&) & = default;

(或者如果编译器生成的实现不符合您的目的,则提供正确的实现。)

答案 1 :(得分:1)

在此代码中:

MyStruct a,b,c,d;
b+c=d;

在您定义operator+()函数后,它会返回MyStruct。因此b+c调用您定义的函数,返回MyStruct,然后在operator=()上调用MyStruct函数,并传递d作为一个论点。

虽然临时MyStruct is an rvalue由于其临时性质,但由于我上面解释的原因,以及C ++标准不禁止调用{{1}这一事实,代码仍会编译当rvalue是用户定义的对象而不是整数类型时,函数在rvalue上。

在此代码中:

operator=()

int a,b,c,d; b+c=d; 返回一个r值int。在b+c运算符的左侧有一个r值不是C ++语法。无论哪种方式,为它分配值都没有任何意义,而在临时=上调用operator=()函数可能会产生副作用。