C++プログラマ キャスブログ
[C++14]2進数リテラルの到来!~桁区切りを添えて~ 2014年11月24日22:04:14
待ちに待った2進数リテラルがC++14でついに搭載されます。 もう脳内で2進数を16進数に変換する時代は終わりを迎えようとしています。 ヨカッタ… ヨカッタ… 書き方はこちら。
1 2 3 4 5 6 7 8 #include <cstdio> // printfに必要なヘッダー int main() { // 0bの後に2進数を並べます。※bは大文字BでもOK printf( "%d\n", 0b1000); return 0; }
出力 8
えっ、桁数が増えると非常に見にくい? ごもっともな指摘です。
1 2 // 32桁の例 0b10001010101111010101010101111000
そこで桁区切りの出番です。 様々な事情を経て[']シングルクォーテーションが桁区切り文字となりました。 こんな感じに4桁ずつに区切ると見やすくなります。
1 0b1000'1010'1011'1101'0101'0101'0111'1000
やっぱり見にくい? そういった方は16進数を使って下さい… 余談ですが、printfの2進数対応はされないのですかね。
[C++11]オブジェクト配列やstd::vectorの初期化は波カッコで行おう! 2014年11月24日20:30:39
記事の説明順が前後して申し訳ありません。 波カッコの初期化の説明をすっ飛ばして何気なく使っていました。 ※英名はuniform initializationらしいのですが、いい和名が欲しいですね。 便利な機能なのでぜひともご活用下さい。 これまでデータ型やデータ型のみで構成された構造体の初期化はこんな書き方で出来ていました。
1 int arr[] = { 1, 2, 3 };
std::vectorには上記の書き方で初期化が出来ませんでしたがC++11から出来るようになりました。 とても便利ですね。
1 2 #include <vector> // std::vectorに必要なヘッダー std::vector<int> arr = { 1, 2, 3 };
また{}がコンストラクタ呼び出しとして利用できるので オブジェクト配列に対してコンストラクタ引数の指定が簡単になりました。 文句なしの機能ですね!
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 30 #include <cstdio> // printfに必要なヘッダー #include <vector> // std::vectorに必要なヘッダー class Test { public: Test( int a, int b, const char* str) { printf( "%d, %d, %s\n", a, b, str ); } }; int main() { // 簡易化されたオブジェクト配列の初期化 Test arr[] = { {10, 1, "hoge"}, {11, 2, "piyo"}, }; // std::vectorでもOK // std::vector<Test> vec = // { // {10, 1, "hoge"}, // {11, 2, "piyo"}, // }; return 0; }
出力 10, 1, hoge 11, 2, piyo
[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