[問題] temporary 可以take reference 嗎?

作者: amamoimi (佛仔)   2024-04-11 20:27:08
c++新手最看了一些文章,發現一個問題,舉個例子:
#include <iostream>
class A{
public:
int a=5;
int& g(){
return a;
}
A f(){
return *this;
}
};
int main()
{
A obj;
std::cout<<obj.f().g();
return 0;}
因為obj.f()的lifetime會持續到
std::cout<<obj.f().g();
這個line結束,所以g取obj.f().a的reference是ok的
但我還是覺得很疑惑,對temporary object 取reference 一般是不行的吧?
舉例來說
int foo1(int a){
return a;}
int main(){
int& b=foo(5);}
如果說foo(5)會存在直到
int& b=foo(5)
這行結束,那這個code不是應該也ok嗎
或是
int& foo2(int a){
return a;}
int main(){
int b=foo2(5);
std::cout<<foo2(5);}
同理這個不是也應該ok了嗎..
這個是可以compile,但是不會cout出東西
把他丟去compiler explorer的話會發現foo2會直接回傳0(?)
我覺得越來越不懂了,求解@@
謝謝大家
作者: jack7775kimo (阿龐)   2024-04-11 21:24:00
關鍵字:value categorycppreference上應該都能找到解釋以上是回答第二個問題;最初那個obj.f()問題是因為RVO,所以obj.f()會拿到obj.a 不是暫時物件更正:就算compiler因沒有RVO而拿到暫時物件,也無妨
作者: Dracarys (MayShowGunMore)   2024-04-11 21:46:00
1. int&可以bind到A::g中的a,因為a是lvalue2. int& b = foo1(5)違法是因為foo1(5)是prvalue (purervalue)3. foo2在C++20及以前都編得過,但是return的reference是dangle的,去印出來是未定義行為。C++23 P2266R3開始,a作為return的operand是xvalue,不能被bound to non-const lvalue reference,int&改成int&&或const int&才編得過。http://wg21.link/P2266R3
作者: wulouise (在線上!=在電腦前)   2024-04-11 22:10:00
通常guideline是永遠不要這麼做,比較節省維護心力
作者: Dracarys (MayShowGunMore)   2024-04-11 23:10:00
Non-const lvalue reference只能bind to lvalue不能rvalue (含xvalue、prvalue)a是不是lvalue跟obj.f()沒關係,通常寫一個變數名都是lvalue expression ,例外我只想得到C++23改的那個case
作者: jack7775kimo (阿龐)   2024-04-12 07:53:00
要看compiler廠商怎麼實作,但一般來說你這樣寫會有
作者: amamoimi (佛仔)   2024-04-12 09:57:00
不知道為什麼我編輯之後推文整個亂掉了...j大的推文好像被截掉了,真的很不好意思@@
作者: jack7775kimo (阿龐)   2024-04-12 11:38:00
1)更正前述的obj.a應是obj2) 改code,意圖也跟著變了;原先f是拿到obj自己,新的是拿到obj的複製體. (但這不影響有沒有RVO)
作者: Dracarys (MayShowGunMore)   2024-04-12 16:30:00
Value category是expression的屬性,obj.f()跟a是不同expr.所以我前面才說沒關係
作者: amamoimi (佛仔)   2024-04-12 16:59:00
那如果我說: obj.f()是temporary,那以它呼叫g()時,g會把這個temporary object 當成有名字的物件,是嗎xd
作者: LPH66 (-6.2598534e+18f)   2024-04-13 14:36:00
再說一次, value category 是式子的屬性, 不是物件的屬性即使在不同狀況下參照到同一個物件仍然可能是不同 category(因此才會有延長物件壽命的規則, 因為 category 可能變化)
作者: firejox (Tangent)   2024-04-13 23:06:00
可以先看這篇 #19gioP8j (C_and_CPP) 這樣會比較好理解
作者: amamoimi (佛仔)   2024-04-14 06:49:00
謝謝文章!我覺得我應該懂我第一個例子為什麼valid了...(其實學校學的c++都還是很原始的版本,但是每次遇到問題,好像都需要用到c++11(?的觀念去解決..)另外雖然value指的是expression,但是我怎麼覺得有好幾個地方他指的都是物件啊(或是參數、運算元,總之就是一個名詞(?)
作者: firejox (Tangent)   2024-04-14 19:20:00
因為要考慮到123、true等常數的情況,所以表達上用value

Links booklink

Contact Us: admin [ a t ] ucptt.com