Re: [問題] 關於C++的Rvalue reference
※ 引述《hpps (hpps)》之銘言:
: 我想問的是,如果我寫
: s3 = s1 + s2;
: 用的是Rvalue reference的版本,那這樣s1不是會被修改到嗎?
不會,這個用的是 LRef 的版本,以下詳述。
: 如果我不想要s1不被修改( 可能之後會用 ),又不想失去效率,
: 那該如何寫比較好??
試考慮這兩個 overloading
// [1] LRef + LRef
string operator+(const string& a, const string& b) { return a + b; }
// [2] RRef + LRef
string operator+(string&&a, const string& b) { return a +=b ; }
(兩個版本的第二個參數都是 LRef,我們不鳥他,只專注在第一個參數)
注意,這兩個版本,是兩個同時都存在,不是只有一個,所以叫做 overloading。
考慮下面這個運算式
string s1;
string s2;
string s3;
string s4 = s1 + s2 + s3;
注意 s4 這行,他實際上會被分成兩步來作
1. 計算 s1 + s2,結果是 (tmp)
2. 計算 (tmp) + s3
現在因為你有兩個版本的 operator+,
所以會呼叫到哪一個,其實需要經過多載決議(overloading resolution)才知道。
先講答案,第一步 s1 + s2 呼叫的是 [1] LRef + LRef 的版本,
第二步 (tmp) + s3 呼叫的是 [2] RRef + LRef 的版本。
差別在於 s1 是個 lvalue,而 (tmp) 是個 non-const rvalue,
non-const rvalue 的特色就是
「他等一下就要煙消雲散了,等一下你就沒有機會碰到他了」
而且!他其實不在意你修改他,因為他是 non-const。
既然他不介意你修改他,而且他馬上就要煙消雲散了,
也就是說「即使你現在亂改,也不會有人發現」
而所謂亂改,表示你可以直接把他裡面的資源,甚至他本身,都整個拿來重新使用。
(反正他等一下就要蒸發了,你不幹白不幹)
所以你在實作 RRef + LRef 這個版本的時候,
就可以放心的使用 a,因為他不可能再被別人使用。
只有在運算式計算值的這個過程的這個當下的唯一這個時間點,你有機會碰到他。
因為 rvalue 就是暫時變數,暫時變數就沒有名字,你不可能再遇到他了。
你說「我之後可能還會用到 s1」
但不用擔心,因為 s1 + s2 會呼叫的是 LRef + LRef 的版本,
你注意這個版本,兩個參數都被 const 修飾,
所以你的實作的既不能、也無法去修改 s1。
也就是說,透過 overloading 兩個版本:
1. const lvalue
2. non-const rvalue
你就可以兼顧安全跟效率
--
To iterate is human, to recurse, divine.
遞迴只應天上有, 凡人該當用迴圈. L. Peter Deutsch
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 58.115.141.224
推
03/24 23:47, , 1F
03/24 23:47, 1F
推
03/25 00:27, , 2F
03/25 00:27, 2F
推
03/25 02:33, , 3F
03/25 02:33, 3F
→
03/25 02:38, , 4F
03/25 02:38, 4F
→
03/25 07:21, , 5F
03/25 07:21, 5F
推
03/26 08:56, , 6F
03/26 08:56, 6F
推
03/27 01:12, , 7F
03/27 01:12, 7F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):