[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;
} |
出力:
コンストラクタ |
|