作者loveme00835 (高髮箍)
看板C_and_CPP
標題Re: [問題] vector複製時間消耗
時間Sat Feb 16 16:38:23 2013
※ 引述《suhorng ( )》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: 平台可能是 mingw32 或 (32||64) 位元的 Ubuntu
: G++ >= 4.6.2, with -std=c++0x (-std=c++11) flags on
: 問題(Question):
: 想請問一下, 我的程式中有如下片段
: vector<my_type> result;
: if (condition)
: result = function1();
: else
: result = function2();
: 而 function1, function2 的 prototype 皆為
: vector<my_type> functionX();
: 那麼我需要擔心那兩行賦值所花的時間嗎?
: 還是其實並不會有複製的動作?
: 另外請問有沒有推薦關於 C++ 這方面規定/G++現有的實做方面的資料呢?
: 之前想測試這類 return (by value, by ref) 以及宣告新變數時會呼叫 operator=,
: copy constructor, 或是普通的建構子, 可是結果跟我胡亂猜測的差很多..
: 另外, 假如我在函式的參數中用 call by value, 那標準函式庫中的容器(特別是vector)
: 有可能自己優化掉改用 R-value reference (若我剛好傳給他的是 R-value)嗎?
: 麻煩各位大大解惑了, 謝謝! <(_ _)>
functionX().swap( result );
以上是在沒有 C++1x 支援下的常見寫法.
即使在有 C++1x 的支援下, 要確保 move 語意, 還要注意任何
擁有權轉移的地方, 此例為兩個:
(1) return local object from function
(2) assigned by return value
--
result = functionX();
// 這邊右運算元是右值, 沒問題
std::vector<my_type>
functionX() {
// ...
return std::move( result );
}
這在 multiple exit point functions 無法做 RVO, 或是
two-stage overload resolution failed 時是一個還不錯
的解決方案. (n3242 §12.8/32 [class.copy])
另外, 你的程式碼太長無法充分表達
條件初始化語意
vector<my_type> result;
// ... do something bad
if ( condition ) {
// ...
}
else {
// ...
}
solution 1:
vector<my_type> result{ condition ? function1() : function2() };
solution 2:
// no move needed
vector<my_type>
&& result = (condition) ? function1() : function2();
--
一個大原則是: 只要一個變數出現, 它的狀態就應該是合法的.
--
if you wanna ask question, use a
SSCCE (
http://sscce.org/ ).
everyone will be
happy to do you a favor.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.221.215
→ adxis:不太了解為何需要 std::move(result) ? 02/16 16:43
→ loveme00835:因為要把存結果物件的資源轉移出來 02/16 16:45
推 suhorng:喔喔!! 謝謝板大 完全忘了還有 .swap 可以用 02/16 17:00
→ suhorng:我好好研究一下 真是太感謝了 02/16 17:01
→ adxis:如果考慮符合 C++11 的 std::vector, 應該具備 move ctor 02/16 17:14
→ adxis:這樣應該不用再加上 std::move 吧? 02/16 17:15
→ loveme00835:你的區域變數已經是左值了, 要用它來初始化暫時物件 02/16 17:17
→ loveme00835:當然需要 std::move() 而那個被初始化的暫時物件才是 02/16 17:17
→ loveme00835:你認為被回傳的那個 02/16 17:17
※ 編輯: loveme00835 來自: 140.121.221.215 (02/16 17:55)
→ suhorng:solution 1 那邊是大括弧嗎? 02/16 18:35
→ loveme00835:yes, 那是為了怕小括號讓編譯器搞錯語意導入的語法, 02/16 18:52
→ loveme00835:不過對std::vector, std::list等容器不建議傳兩個引數 02/16 18:55