函数返回结构为LValue [英] Function returning struct as LValue

查看:116
本文介绍了函数返回结构为LValue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码片段中,为什么行 o.margin()= m; 没有错误编译?它很容易得到警告,因为它几乎总是一个错误。我真的会认为这是一个错误,因为它将一个R值放在赋值的左边。

  #include< iostream> 

结构保证金
{
保证金(int val = 0):val(val){};
int val;
};

结构选项
{
保证金m;
int z = 0;

保证金保证金()const {return m; }
int zoomLevel(){return z; }
};


int main()
{
Option o;
std :: cout<< 保证金是:<< o.margin()。val<<的std :: ENDL;

保证金m = {3};

//下面一行是no-op,它不会产生警告:
o.margin()= m;

//以下行是错误
// GCC 4.9.0:错误:作为赋值左操作数所需的左值
// clang 3.8:错误:表达式不是可分配
// MSVC 2015:错误C2106:'=':左操作数必须为l值
o.zoomLevel()= 2;

std :: cout<< 保证金是:<< o.margin()。val<<的std :: ENDL;

返回0;
}

输出:

 保证金为:0 
保证金为:0


解决方案

您可以修改类类型的返回类型(通过调用非const方法):

3.10 / 5 from n4140


5为了修改对象
,需要一个对象的左值,除了类类型的右值也可以在某些情况下用于修改其
指标。 [例如:为对象(9.3)调用的成员函数
可以修改对象。

您的代码:

  o.margin()= m; 

实际上与

  o.margin()。operator =(Margin(m)); 

所以调用非const方法,如果将其更改为:

  o.margin()。val = m; 

然后您将收到错误消息。

另一方面在这里:

o.zoomLevel()= 2;

zoomLevel()返回非类类型,所以你不能修改它。


In the following snippet, why does the line o.margin() = m; compile without fault? It easily deserves a warning, since it will almost invariably be a mistake. I would actually have thought it to be an error since it puts an R-Value on the left side of an assignment.

#include <iostream>

struct Margin
{
    Margin(int val=0) : val(val) {};
    int val;
};

struct Option
{
    Margin m;
    int z=0;

    Margin margin()const { return m; }
    int zoomLevel() { return z; }
};


int main()
{
    Option o;
    std::cout << "Margin is: "<< o.margin().val << std::endl;

    Margin m = { 3 };

    // The following line is a no-op, which generates no warning:
    o.margin() = m;

    // The following line is an error
    // GCC 4.9.0: error: lvalue required as left operand of assignment
    // clang 3.8: error: expression is not assignable
    // MSVC 2015: error C2106: '=': left operand must be l-value
     o.zoomLevel() = 2;

    std::cout << "Margin is: "<< o.margin().val << std::endl;

    return 0;
}

Output:

Margin is: 0
Margin is: 0

解决方案

You are allowed to modify return types of class type (by calling non const methods on it):

3.10/5 from n4140

5 An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [ Example: a member function called for an object (9.3) can modify the object. —end example ]

your code:

o.margin() = m;

is actually the same as

o.margin().operator=( Margin(m) );

so non const method is called, if you change it to:

o.margin().val = m;

then you will get an error.

on the other hand here:

o.zoomLevel() = 2;

zoomLevel() returns non-class type, so you cannot modify it.

这篇关于函数返回结构为LValue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆