[英]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.