|
|
[C++14]2進数リテラルの到来!~桁区切りを添えて~ |
2014年11月24日22:04:14 |
|
待ちに待った2進数リテラルがC++14でついに搭載されます。
もう脳内で2進数を16進数に変換する時代は終わりを迎えようとしています。
ヨカッタ… ヨカッタ…
書き方はこちら。 |
1
2
3
4
5
6
7
8
| #include <cstdio>
int main()
{
printf( "%d\n", 0b1000);
return 0;
} |
出力
8 |
えっ、桁数が増えると非常に見にくい?
ごもっともな指摘です。 |
1
2
|
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<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>
#include <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"},
};
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>
#include <cstdio>
class Test
{
public:
Test(int i)
{
printf( "コンストラクタ\n");
}
Test(const Test&)
{
printf( "コピーコンストラクタ\n");
}
};
int main()
{
std::vector<Test> vec;
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>
#include <cstdio>
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>
#include <cstdio>
class Test
{
public:
Test(int i)
{
printf( "コンストラクタ\n");
}
Test(const Test&)
{
printf( "コピーコンストラクタ\n");
}
};
int main()
{
std::vector<Test> vec;
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>
#include <cstdio>
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;
} |
出力:
コンストラクタ |
|
|