[英]Function returning struct as LValue
在下面的代码片段中,为什么行o.margin() = m;
编译无故障? 它很容易引起警告,因为它几乎总是一个错误。 我实际上认为它是一个错误,因为它在赋值的左侧放置了一个R值。
#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;
}
输出:
Margin is: 0
Margin is: 0
您可以修改类类型的返回类型(通过调用非const方法):
3.10 / 5来自n4140
5为了修改对象,对象的左值是必要的,除了在某些情况下也可以使用类类型的右值来修改它的指示对象。 [示例:调用对象(9.3)的成员函数可以修改对象。 - 末端的例子]
你的代码:
o.margin() = m;
实际上是一样的
o.margin().operator=( Margin(m) );
因此,如果将其更改为:const const方法,则调用它:
o.margin().val = m;
然后你会得到一个错误。
另一方面,这里:
o.zoomLevel()= 2;
zoomLevel()
返回非类类型,因此您无法修改它。
当o
是类类型的对象时, operator=
是成员函数。 代码o.margin() = m;
相当于o.margin().operator=(m);
。
您可以调用临时类对象的成员函数,类似于访问o.margin().val
的成员的o.margin().val
。
此外,类的赋值运算符可以被覆盖,而根本不是无操作符。
Option::margin()
是一个const 可访问的成员函数,它返回一个可变的Margin
对象。
因此,分配临时值是有效的,因为使用operator=
on Margin
是有效的。 在这种情况下,它没有副作用,基本上什么也没做。 C ++编译器的特定实现可以选择实现语义分析并警告您,但它完全超出了语言的范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.