当我尝试编译以下程序时,我得到一个有意义的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吗?那它怎么编译
答案 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=()
函数可能会产生副作用。