C++ 需要r值概念方面的帮助吗

C++ 需要r值概念方面的帮助吗,c++,c++11,lvalue,rvalue,C++,C++11,Lvalue,Rvalue,当我尝试编译下面的程序时,我得到了一个关于l值的错误,这是有意义的。 错误为:错误C2106:“=”:左操作数必须是l值 代码: 但当我用自己的结构替换integer时,下面的代码工作得非常好 struct MyStruct { int val; MyStruct(){} }; MyStruct operator+(MyStruct& s1, MyStruct& s2) { MyStruct temp; return temp; } int m

当我尝试编译下面的程序时,我得到了一个关于l值的错误,这是有意义的。 错误为:错误C2106:“=”:左操作数必须是l值

代码:

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

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;
}
第二段代码是如何编译的? 我知道我可以从操作符+返回常量。但第二个例子中的b+c不是右值吗?那么它是如何编译这段代码的呢

MyStruct a,b,c,d;
b+c=d;
int a,b,c,d;
b+c=d;
定义了
operator+()
函数后,它返回一个
MyStruct
。因此,调用您定义的函数的
b+c
,返回一个
MyStruct
,然后对该
MyStruct
调用
操作符=()
函数,并将其作为参数传递给
d

尽管临时代码> MyStult<代码>由于其临时性,但由于上面解释的原因,代码仍然编译,并且C++标准不允许在rof是一个用户定义的对象而不是一个整数类型时在rof上调用<代码>运算符=(/)>代码>函数。 在此代码中:

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

<代码> B+C 返回r值int。在 = /Cux>运算符左侧具有R值不是C++语法。无论哪种方式,给它赋值都没有任何意义,而对临时的

MyStruct
调用
操作符=()
函数可能会产生副作用。

已经解释了代码编译的原因

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

MyStruct& operator =(const MyStruct&) && = delete;
MyStruct& operator =(const MyStruct&) & = default;
这告诉编译器,每次对作为右值的
MyStruct
对象调用
运算符=()
(由于ref限定符
&&
),代码都不应该有效,因为
运算符=()
不存在(
=delete;
)。事实上,GCC 4.8.1包含以下内容:

错误:使用已删除的函数“MyStruct&MyStruct::operator=(const MyStruct&)&&”

更新:以下是作者的评论(非常感谢)

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

b = c;
如果要禁用对右值的赋值,但仍允许对左值进行赋值,则将此项添加到
MyStruct

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

(或者如果编译器生成的一个不符合你的目的,那么就提供一个正确的实现)。< /P>如果它不是C++语法,那么它编译的结果如何呢?相反,如果我写(b+c).val=d.val,这一个失败没有编译,你自己这么说-它会得到错误代码C2106。代码< > MyStult代码是正确的C++语法,因此编译。谢谢您的澄清。我想我的基本问题是为什么临时Mystruct不是r-value@Cory克莱恩:“那个临时的MyStruct不是r值。”。实际上,临时值是一个右值。问题是类类型的右值的行为与类型中bult的右值不同(正如您已经清楚解释的那样)。我更新了答案,解释了为什么

MyStruct
不是右值。我一直在使用
MyStruct&operator=(const-MyStruct&)&=default以达到相同的目的。你能想出什么理由支持删除而不是默认吗?@Casey:我不知道这样做也会有同样的效果。实际上你的解决方案比我的好,我会更新我的答案。谢谢你。