Re: [問題] vector複製時間消耗

看板C_and_CPP作者 (高髮箍)時間11年前 (2013/02/16 16:38), 編輯推噓1(1011)
留言12則, 3人參與, 最新討論串2/3 (看更多)
※ 引述《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

02/16 16:43, , 1F
不太了解為何需要 std::move(result) ?
02/16 16:43, 1F

02/16 16:45, , 2F
因為要把存結果物件的資源轉移出來
02/16 16:45, 2F

02/16 17:00, , 3F
喔喔!! 謝謝板大 完全忘了還有 .swap 可以用
02/16 17:00, 3F

02/16 17:01, , 4F
我好好研究一下 真是太感謝了
02/16 17:01, 4F

02/16 17:14, , 5F
如果考慮符合 C++11 的 std::vector, 應該具備 move ctor
02/16 17:14, 5F

02/16 17:15, , 6F
這樣應該不用再加上 std::move 吧?
02/16 17:15, 6F

02/16 17:17, , 7F
你的區域變數已經是左值了, 要用它來初始化暫時物件
02/16 17:17, 7F

02/16 17:17, , 8F
當然需要 std::move() 而那個被初始化的暫時物件才是
02/16 17:17, 8F

02/16 17:17, , 9F
你認為被回傳的那個
02/16 17:17, 9F
※ 編輯: loveme00835 來自: 140.121.221.215 (02/16 17:55)

02/16 18:35, , 10F
solution 1 那邊是大括弧嗎?
02/16 18:35, 10F

02/16 18:52, , 11F
yes, 那是為了怕小括號讓編譯器搞錯語意導入的語法,
02/16 18:52, 11F

02/16 18:55, , 12F
不過對std::vector, std::list等容器不建議傳兩個引數
02/16 18:55, 12F
文章代碼(AID): #1H7qM9AX (C_and_CPP)
文章代碼(AID): #1H7qM9AX (C_and_CPP)