3

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

代码:

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;
}

第二个代码是怎么编译的?我知道我可以从 operator+ 返回 const。但是第二个例子中的 b+c 不是右值吗?那么它是如何编译的

4

2 回答 2

2

Cory Klein已经在这里解释了代码编译的原因。

我只想补充一点,如果你想MyStruct表现得像ints (和其他内置类型),那么将此行添加到MyStruct

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

这告诉编译器,每次在右值对象operator =()上调用MyStruct(由于ref-qualifier &&)代码不应该是有效的,因为operator =()不存在(= delete;)。实际上,GCC 4.8.1 发出以下内容:

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

b+c=d;
   ^

更新:根据凯西的评论(非常感谢)。

将上面的行添加到MyStruct. 它还可以防止分配给左值。也就是说,下面的行也变得非法:

b = c;

如果您想禁用对右值的赋值但仍允许对左值进行赋值,则代替上面的行,将这一行添加到MyStruct

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

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

于 2013-07-19T18:23:54.397 回答
1

在这段代码中:

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

正如您定义的operator+()函数,它返回一个MyStruct. 因此b+c, which 调用你定义的函数,返回 a MyStruct,然后operator=()在 that 上调用函数MyStruct,并将它d作为参数传递。

尽管由于其临时性质,临时MyStruct 是右值,但由于我上面解释的原因,代码仍然可以编译,并且operator=()当右值是用户定义的对象而不是一个整数类型。

在这段代码中:

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

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

于 2013-07-19T18:16:33.510 回答