template <class... Args>
iterator emplace(Args&&... args);
概要
コンテナ内へ要素を直接構築する
要件
このコンテナの要素型 value_type
は、コンテナに対して引数 args
から直接構築可能(EmplaceConstructible)でなければならない。
ここで、コンテナに対して引数 args
から直接構築可能とは、m
をアロケータ型 allocator_type
の左辺値、p
を要素型 value_type
へのポインタとすると、以下の式が適格(well-formed)であるということである。
std::allocator_traits<allocator_type>::construct(m, p, std::forward<Args>(args)...);
効果
std::forward<Args>(args)...
から構築された value_type
のオブジェクト t
をコンテナに挿入する。
なお、オブジェクト t
は、構築後にコンテナにコピー、あるいはムーブされるわけではなく、コンテナ内に直接構築される。
戻り値
追加された要素を指すイテレータ。
例外
ハッシュ関数以外から例外が投げられた場合には、挿入はされない。
計算量
平均的なケースでは定数(O(1
))だが、最悪のケースではコンテナの要素数に比例(O(size()
))。
備考
-
この関数が呼ばれた後も、当該コンテナ内の要素を指す参照は無効にはならない。
なお、規格書に明確な記載は無いが、当該コンテナ内の要素を指すポインタも無効にはならない。 -
この関数が呼ばれた後も、呼び出しの前後でこのコンテナのバケット数(
bucket_count()
の戻り値)が変わらなかった場合には当該コンテナを指すイテレータは無効にはならない。 それ以外の場合は、当該コンテナを指すイテレータは無効になる可能性がある。
コンテナのバケット数が変わらない場合とは、要素追加後の要素数が、要素追加前のバケット数(bucket_count()
の戻り値)×最大負荷率(max_load_factor()
の戻り値)よりも小さかった場合である。
なお、条件が「よりも小さい」となっているが、最大負荷率の定義からすると「以下」の方が適切と思われる。reserve
も参照。 -
このメンバ関数は、コンテナの種類によってシグネチャが異なるため、注意が必要である。
emplace_hint
も含めた一覧を以下に示す。コンテナ シグネチャ シーケンスコンテナ template <class... Args>
iterator emplace(const_iterator, Args&&...)
連想コンテナ、非順序連想コンテナ
(同一キーの重複を許さない場合)template <class... Args>
pair<iterator, bool> emplace(Args&&...)
連想コンテナ、非順序連想コンテナ
(同一キーの重複を許す場合)template <class... Args>
iterator emplace(Args&&...)
連想コンテナ、非順序連想コンテナ template <class... Args>
iterator emplace_hint(const_iterator, Args&&...)
例
#include <iostream>
#include <unordered_set>
#include <string>
#include <utility>
#include <algorithm>
#include <iterator>
// サンプル用クラス
struct is : std::pair<int, std::string> {
is(int i, const char* s) : std::pair<int, std::string>(i, s) {}
is(const is&) = delete; // emplace はコピーコンストラクタが無くても大丈夫
is(is&&) = delete; // もちろんムーブコンストラクタが無くても大丈夫
};
// サンプル用クラスのために std::hash を特殊化
namespace std {
template <>
struct hash<is> : private hash<int>, private hash<string> {
std::size_t operator()(const is& v) const {
return hash<int>::operator()(v.first) ^ hash<string>::operator()(v.second);
}
};
}
// サンプル用クラスのための挿入演算子
std::ostream& operator<<(std::ostream& os, const is& p)
{
return os << '(' << p.first << ',' << p.second << ')';
}
int main()
{
std::unordered_multiset<is> ums;
auto it1 = ums.emplace(1, "1st");
std::cout << *it1 << '\n';
auto it2 = ums.emplace(2, "2nd");
std::cout << *it2 << '\n';
auto it3 = ums.emplace(1, "1st");
std::cout << *it3 << '\n';
//以下はコピー&ムーブコンストラクタが無いのでコンパイルエラーになる
//auto it4 = ums.insert(is(3, "3rd"));
//std::cout << *it4 << '\n';
// 追加結果の出力
std::copy(ums.cbegin(), ums.cend(), std::ostream_iterator<is>(std::cout, ", "));
std::cout << std::endl;
}
std::copy(ums.cbegin(), ums.cend(), std::ostream_iterator<is>(std::cout, ", "));
#include <iostream>
#include <unordered_set>
#include <string>
#include <utility>
#include <algorithm>
#include <iterator>
// サンプル用クラス
struct is : std::pair<int, std::string> {
is(int i, const char* s) : std::pair<int, std::string>(i, s) {}
is(const is&) = delete; // emplace はコピーコンストラクタが無くても大丈夫
is(is&&) = delete; // もちろんムーブコンストラクタが無くても大丈夫
};
// サンプル用クラスのために std::hash を特殊化
namespace std {
template <>
struct hash<is> : private hash<int>, private hash<string> {
出力
(1,1st)
(2,2nd)
(1,1st)
(2,2nd), (1,1st), (1,1st),
注:unordered_multiset
は非順序連想コンテナであるため、出力順序は無意味であることに注意
バージョン
言語
- C++11
処理系
- Clang: 3.1 ✅
- GCC: 4.7.0 ✅
- ICC: ?
- Visual C++: ?
関連項目
名前 | 説明 |
---|---|
emplace_hint |
挿入位置のヒントを使用したコンテナ内への要素の直接構築 |
insert |
要素の追加 |
erase |
要素の削除 |
clear |
全要素の削除 |
swap |
内容の交換 |
bucket_count |
バケット数の取得 |
load_factor |
現在の負荷率(バケットあたりの要素数の平均)を取得 |
max_load_factor |
最大負荷率を取得、設定 |
rehash |
最小バケット数指定によるバケット数の調整 |
reserve |
最小要素数指定によるバケット数の調整 |