template <class T, class... Args>
T& emplace(Args&&... args); // (1) C++17
template <class T, class... Args>
constexpr T& emplace(Args&&... args); // (1) C++23
template <class T, class U, class... Args>
T& emplace(std::initializer_list<U> il, Args&&... args); // (2) C++17
template <class T, class U, class... Args>
constexpr T& emplace(std::initializer_list<U> il, Args&&... args); // (2) C++23
template <std::size_t I, class... Args>
variant_alternative_t<I, variant<Types...>>&
emplace(Args&&... args); // (3) C++17
template <std::size_t I, class... Args>
constexpr variant_alternative_t<I, variant<Types...>>&
emplace(Args&&... args); // (3) C++23
template <std::size_t I, class U, class... Args>
variant_alternative_t<I, variant<Types...>>&
emplace(std::initializer_list<U> il, Args&&... args); // (4) C++17
template <std::size_t I, class U, class... Args>
constexpr variant_alternative_t<I, variant<Types...>>&
emplace(std::initializer_list<U> il, Args&&... args); // (4) C++23
概要
variant
に代入する値を直接構築する。
- (1) : 候補型に含まれる
T
型のオブジェクトを、コンストラクタ引数args...
から構築して保持する - (2) : 候補型に含まれる
T
型のオブジェクトを、コンストラクタ引数il
とargs...
から構築して保持する - (3) :
I
番目の候補型オブジェクトを、コンストラクタ引数args...
から構築して保持する - (4) :
I
番目の候補型オブジェクトを、コンストラクタ引数il
とargs...
から構築して保持する
テンプレートパラメータ制約
- (1) :
is_constructible_v<T, Args...>
がtrue
であることTypes...
内に型T
が一度だけ現れること
- (2) :
is_constructible_v<T, std::initializer_list<U>&, Args...>
がtrue
であることTypes...
内に型T
が一度だけ現れること
- (3) :
I < sizeof...(Types)
であることTypes...
のI
番目の型をTi
として、is_constructible_v<Ti, Args...>
がtrue
であること
- (4) :
I < sizeof...(Types)
であることTypes...
のI
番目の型をTi
として、is_constructible_v<Ti, std::initializer_list<U>&, Args...>
がtrue
であること
効果
-
(1) :
Types...
に含まれる型T
のインデックスをI
として、以下と等価:
return emplace<I>(std::forward<Args>(args)...);
-
(2) :
Types...
に含まれる型T
のインデックスをI
として、以下と等価:
return emplace<I>(il, std::forward<Args>(args)...);
-
(3) :
- 値を保持している場合、破棄する
Types...
のI
番目の型をTi
として、Ti
型オブジェクトをコンストラクタ引数std::forward<Args>(args)...
で構築して保持する
- (4) :
- 値を保持している場合、破棄する
Types...
のI
番目の型をTi
として、Ti
型オブジェクトをコンストラクタ引数il
とstd::forward<Args>(args)...
で構築して保持する
戻り値
新たに保持する値への参照を返す。
事後条件
- (3), (4) :
index()
がI
であること
例外
- (1), (2), (3), (4) : 保持する値の初期化中に例外が発生する可能性があり、その後、
variant
オブジェクトは値を保持しない可能性がある
備考
- この関数は、テンプレート内で使用する場合に、
v.template emplace<T>(args...)
のようにtemplate限定子を指定する必要がある。
例
基本的な使い方
#include <cassert>
#include <variant>
#include <string>
int main()
{
// (1)
{
std::variant<int, char, std::string> v;
// vオブジェクト内でstd::stringオブジェクトを構築して保持
std::string& s = v.emplace<std::string>(3, 'a');
assert(s == "aaa");
assert(std::get<std::string>(v) == "aaa");
}
// (2)
{
std::variant<int, char, std::string> v;
std::allocator<char> alloc;
v.emplace<std::string>({'H', 'e', 'l', 'l', 'o'}, alloc);
assert(std::get<std::string>(v) == "Hello");
}
// (3)
{
std::variant<int, char, std::string> v;
v.emplace<2>(3, 'a');
assert(std::get<2>(v) == "aaa");
}
// (4)
{
std::variant<int, char, std::string> v;
std::allocator<char> alloc;
v.emplace<2>({'H', 'e', 'l', 'l', 'o'}, alloc);
assert(std::get<2>(v) == "Hello");
}
}
出力
同じ型を複数指定できる状況の例
#include <cassert>
#include <variant>
#include <string>
int main()
{
// インデックスを指定した代入なら、同じ型が複数現れてもよい。
// 代入演算子、emplace<T>()、std::get<T>()、std::holds_alternative<T>()は使用できない。
// in_place_index<I>を指定するコンストラクタ、emplace<I>()、std::get<I>(), index()は使用できる
std::variant<std::string, std::string> v;
v.emplace<0>("abc"); // OK
std::string& s = std::get<0>(v);
assert(s == "abc");
//v.emplace<std::string>("abc"); // コンパイルエラー!
//v = "abc"; // コンパイルエラー!
}
出力
バージョン
言語
- C++17
処理系
- Clang: 4.0.1
- GCC: 7.3
- Visual C++: ??