※ 本文轉寄自 ptt.cc, 文章原始頁面
看板C_and_CPP
標題

[問題] temporary 可以take reference 嗎?

最新2024-04-14 19:20:00
留言41則留言,6人參與討論
推噓5 ( 5036 )
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(?) 我覺得越來越不懂了,求解@@ 謝謝大家 ---- Sent from BePTT on my OPPO CPH1943 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.200.14.226 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1712838430.A.E4C.html

41 則留言

jack7775kimo, 1F
關鍵字:value category

jack7775kimo, 2F
cppreference上應該都能找到解釋

jack7775kimo, 3F
以上是回答第二個問題;最初那個obj.f()問題是因為

jack7775kimo, 4F
RVO,所以obj.f()會拿到obj.a 不是暫時物件

jack7775kimo, 5F
更正:就算compiler因沒有RVO而拿到暫時物件,也無妨
謝謝! 那如果f改成{A obj2; return obj2;}還會有RVO嗎(改成這樣output跟原來一樣)

Dracarys, 6F
1. int&可以bind到A::g中的a,因為a是lvalue
謝謝! 1.的 a是lvalue? 但是obj.f() 應該是temporary 那就不應該是lvalue不是嗎0.0

Dracarys, 7F
2. int& b = foo1(5)違法是因為foo1(5)是prvalue (pure
嗯嗯所以lvalue reference應該還是是不能bind to xvalue 或是prvalue囉xd(混亂

Dracarys, 8F
rvalue)

Dracarys, 9F
3. foo2在C++20及以前都編得過,但是return的reference

Dracarys, 10F
是dangle的,去印出來是未定義行為。C++23 P2266R3開始

Dracarys, 11F
,a作為return的operand是xvalue,不能被bound to non-

Dracarys, 12F
const lvalue reference,int&改成int&&或const int&才

Dracarys, 13F
編得過。

Dracarys, 14F

wulouise, 15F
通常guideline是永遠不要這麼做,比較節省維護心力
謝謝,也是沒有書會這樣寫xd
※ 編輯: amamoimi (1.200.14.226 臺灣), 04/11/2024 22:35:00

Dracarys, 16F
Non-const lvalue reference只能bind to lvalue

Dracarys, 17F
不能rvalue (含xvalue、prvalue)

Dracarys, 18F
a是不是lvalue跟obj.f()沒關係,通常寫一個變數名都是l

Dracarys, 19F
value expression ,例外我只想得到C++23改的那個case
也就是說obj.f()本來是rvalue,但是到g裡就被當成成lvalue了嗎!?為什麼會這樣...

jack7775kimo, 20F
要看compiler廠商怎麼實作,但一般來說你這樣寫會有

amamoimi, 21F
不知道為什麼我編輯之後推文整個亂掉了...j大的推文好

amamoimi, 22F
像被截掉了,真的很不好意思@@
※ 編輯: amamoimi (180.217.14.80 臺灣), 04/12/2024 10:19:43

jack7775kimo, 23F
1)更正前述的obj.a應是obj

jack7775kimo, 24F
2) 改code,意圖也跟著變了;原先f是拿到obj自己,新的

jack7775kimo, 25F
是拿到obj的複製體. (但這不影響有沒有RVO)

amamoimi, 26F
謝謝j大復原!
※ 編輯: amamoimi (140.138.31.178 臺灣), 04/12/2024 12:56:17

Dracarys, 27F
Value category是expression的屬性,obj.f()跟a是不同e

Dracarys, 28F
xpr.所以我前面才說沒關係

amamoimi, 29F
那如果我說obj.f()是temporary,那以它呼叫g()時,g

amamoimi, 30F
會把這個temporary object 當成有名字的物件,是嗎xd

LPH66, 31F
再說一次, value category 是式子的屬性, 不是物件的屬性

LPH66, 32F
即使在不同狀況下參照到同一個物件仍然可能是不同 category

LPH66, 33F
(因此才會有延長物件壽命的規則, 因為 category 可能變化)

firejox, 34F
可以先看這篇 #19gioP8j (C_and_CPP) 這樣會比較好理解

amamoimi, 35F
謝謝文章!我覺得我應該懂我第一個例子為什麼valid了..

amamoimi, 36F
.(其實學校學的c++都還是很原始的版本,但是每次遇到

amamoimi, 37F
問題,好像都需要用到c++11(?的觀念去解決..)另外雖

amamoimi, 38F
然value指的是expression,但是我怎麼覺得有好幾個地方

amamoimi, 39F
他指的都是物件啊(或是參數、運算元,總之就是一個名

amamoimi, 40F
詞(?)

firejox, 41F
因為要考慮到123、true等常數的情況,所以表達上用value

amamoimi 作者的近期文章

[問題] 用函數設定參照的問題
各位晚安打擾了 https://onlinegdb.com/_DyNuxd2H 我一直不太明白為什麼為什麼這樣寫是合法的 f(a)=5這行不是在把function call設值嗎 但是照理來說只能assign value給變數吧?(gpt這
[問題]char 指標問題
不好意思我程式新手又來擾民了@@ https://onlinegdb.com/Vm941gQ0_ 這是我在書上看到的程式碼 功能是把變數byte by byte的交換 但是我看不太懂那個swap函數... 為什麼可以隨便把參數冠上一個(ch
[問題] 遞迴函數的變數儲存
不好意思又是我c++新手 想問一個問題 舉個例子 #include&lt;iostream&gt; using namespace std; void f(int); int main(){ f(2); return 0;} void f(
更多 amamoimi 作者的文章...