C++1zでは、2つの連想コンテナを接合(splice)する機能が入ります。対象は、map
、set
、unordered_map
、unordered_set
とそれらのmulti版すべてです。
まず、特定の要素を抽出する機能として、extract()
メンバ関数が追加されます。
node_type extract(const_iterator position);
node_type extract(const key_type& x);
要素を抽出する操作にともない、すべての連想コンテナに、node_type
という入れ子型が追加されます。その実装となる型は、標準ライブラリの機能としては定義されず、連想コンテナの要件としてnode_type
ができることが定義されます。
次に、抽出した要素をほかのコンテナに挿入する機能として、insert()
メンバ関数にnode_type
を受け取るオーバーロードが追加されます。
insert_return_type insert(node_type&& nh); iterator insert(const_iterator hint, node_type&& nh);
この挿入機能のために、非multi連想コンテナにinsert_return_type
という入れ子型が追加されます。multi連想コンテナはiterator
を返します。insert_return_type
型も標準ライブラリの機能としてではなく、要件として定義されます。この型は、以下のメンバ変数を持ちます:
bool inserted; // 挿入が成功したか X::iterator position; // 挿入した要素を指すイテレータ X::node_type node; // 指定されたノード
最後に、2つの連想コンテナをまるまる接合するmerge()
メンバ関数が追加されます。このメンバ関数は、multi版と非multi版の両方のコンテナを受け取れます。たとえばmap
の場合は、以下のメンバ関数を持ちます。
template <class C2> void merge(map<Key, T, C2, Allocator>& source); template <class C2> void merge(map<Key, T, C2, Allocator>&& source); template <class C2> void merge(multimap<Key, T, C2, Allocator>& source); template <class C2> void merge(multimap<Key, T, C2, Allocator>&& source);
サンプルコード : 抽出と挿入
#include <map> #include <string> int main() { std::map<int, std::string> src {{1,"one"}, {2,"two"}, {3,"buckle my shoe"}}; std::map<int, std::string> dst {{3,"three"}}; dst.insert(src.extract(src.find(1))); // イテレータ版 dst.insert(src.extract(2)); // キー版 // 挿入先にすでに同一キーの要素がある場合は、挿入されない auto r = dst.insert(src.extract(3)); // src == {} // dst == {"one", "two", "three"} // r.position == dst.begin() + 2 // r.inserted == false // r.node == "buckle my shoe" }
サンプルコード : コンテナまるごとマージ
#include <set> int main() { std::set<int> src{1, 3, 5}; std::set<int> dst{2, 4, 5}; dst.merge(src); // srcをdstにマージ // マージできなかった要素はsrcに残る // src == {5} // dst == {1, 2, 3, 4, 5} }
参照
- LWG Issue #839 Maps and sets missing splice operation
- LWG Issue #1041 Add associative/unordered container functions that allow to extract elements
- N3586 Splicing Maps and Sets
- N3645 Splicing Maps and Sets (Revision 1)
- P0083R0 Splicing Maps and Sets (Revision 2)
- P0083R1 Splicing Maps and Sets (Revision 3)
- P0083R2 Splicing Maps and Sets (Revision 4)
- P0083R3 Splicing Maps and Sets (Revision 5)
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。