💡 C++ の emplace_back は push_back を完全に置き換えられるか?

📌 この記事は Zenn に投稿した内容のアーカイブです。 はじめに C++11 から導入された emplace_back は、コンテナに要素をその場で構築できる便利なメソッドです。 一方、それ以前から使われてきた push_back とはどんな違いがあり、emplace_back は完全に push_back を代替できるのでしょうか? 本記事では、 emplace_back が本当に push_back より常に速いのか 両者がどんなケースに使えるのか 実装の違いと注意点 について、自分なりに整理した考えをまとめます。 push_back と emplace_back の違い push_back // C++20以降 constexpr void push_back(const T& value); // コピー constexpr void push_back(T&& value); // ムーブ push_back は、すでに生成されたオブジェクトをコピーまたはムーブして格納する関数です。 emplace_back // C++20以降 template<class... Args> constexpr reference emplace_back(Args&&... args); // その場で構築 emplace_back は、コンストラクタに渡す引数をそのまま受け取り、コンテナ内部で直接オブジェクトを構築します。そのため、中間オブジェクトなし に要素を追加できる点が特徴です。 これらの大きな違いは、push_backが既に生成されたオブジェクト(T型)をコピーまたはムーブする一方で、emplace_backは任意のコンストラクタ引数からその場でT型のインスタンスを構築できる点です。 LLVMにおける内部実装 以下はLLVM(libc++)におけるpush_back内部の実装です。 if (this->__end_ != this->__end_cap()) { __construct_one_at_end(__x); // 残り容量がある場合、__xをコピーまたはムーブ構築 } else { __push_back_slow_path(__x); // 足りない場合、新規領域を確保して再配置 } __construct_one_at_end の中では、allocatorが提供する construct() を使って、指定されたメモリにオブジェクトを構築しています。 また、allocatorが construct() を持たない場合には単純に in-place new を呼び出す仕組みです。 ...

2025年6月24日 · 1 分 · 193 文字 · Wuyukwi