C++プログラマ キャスブログ
[C++11]効率的にコンテナへ追加push_backとはおさらばemplace_back 2014年11月24日03:34:30
C++11から右辺値参照とムーブセマンティクス呼ばれる機能が追加されました。 それについては別の回でご紹介したいと思います。 今回はコンテナに追加するメソッドを置き換えるだけで効率的になる手段をお伝えします。 結論から言えば下記のメソッドを置き換えましょう! push_back → emplace_back push_front → emplace_front こちらが参考コードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <vector> //std::vectorを使うためのヘッダー #include <cstdio> //printfを使うためのヘッダー class Test { public: Test(int i) { printf( "コンストラクタ\n"); } Test(const Test&) { printf( "コピーコンストラクタ\n"); } }; int main() { std::vector<Test> vec; // C++11で追加されたコンテナへの追加メソッド // コンテナによってはemplace_frontもあります。 vec.emplace_back(0); return 0; }
出力: コンストラクタ
おおっと、コピーコンストラクタが走っていませんね。 素晴らしい、非常に効率的です。 今までのpush_backを使うとこうなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <vector> //std::vectorを使うためのヘッダー #include <cstdio> //printfを使うためのヘッダー class Test { public: Test(int i) { printf( "コンストラクタ\n"); } Test(const Test&) { printf( "コピーコンストラクタ\n"); } }; int main() { std::vector<Test> vec; // コピーコンストラクタが呼ばれる vec.push_back(0); return 0; }
出力: コンストラクタ コピーコンストラクタ
無駄にコピーコンストラクタが走ってしまっていますね。 これはもう問答無用でemplace_backに置き換えていいと思います! ただし、書き方には注意点があります。 コンストラクタを自分で呼んでしまうとemplace_backが台無しになってしまいます。 必ず暗黙の型変換を行う記述で書いてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // 注意:これはダメなコードです。 #include <vector> //std::vectorを使うためのヘッダー #include <cstdio> //printfを使うためのヘッダー class Test { public: Test(int i) { printf( "コンストラクタ\n"); } Test(const Test&) { printf( "コピーコンストラクタ\n"); } }; int main() { std::vector<Test> vec; // コンストラクタを呼んでしまうダメな例 vec.emplace_back(Test(0)); // これもダメ //vec.emplace_back((Test)0); return 0; }
出力: コンストラクタ コピーコンストラクタ
分かりやすくする為に引数付きのコンストラクタをサンプルに出しましたが 引数なしのコンストラクタを呼ぶ場合は引数なしでemplace_backを呼べばよいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <vector> //std::vectorを使うためのヘッダー #include <cstdio> //printfを使うためのヘッダー class Test { public: Test() { printf( "コンストラクタ\n"); } Test(int) { printf( "引数付きコンストラクタ\n"); } Test(const Test&) { printf( "コピーコンストラクタ\n"); } }; int main() { std::vector<Test> vec; // 引数なしのコンストラクタを呼ぶ場合は空にして下さい。 vec.emplace_back(); return 0; }
出力: コンストラクタ
カテゴリ

リンク
C++11のコードを
試すのに便利です。
http://ideone.com/

同人ゲームを
製作している知人
sorcery

にほんブログ村 IT技術ブログ C/C++へ
にほんブログ村


C++ ブログランキングへ

ゲームダウンロード DefenceTri