std::variant<Types...>::emplace
From cppreference.com
template< class T, class... Args > T& emplace( Args&&... args ); |
(1) | (C++17以降) (C++20 以降 constexpr) |
template< class T, class U, class... Args > T& emplace( std::initializer_list<U> il, Args&&... args ); |
(2) | (C++17以降) (C++20 以降 constexpr) |
template< std::size_t I, class... Args > std::variant_alternative_t<I, variant>& emplace( Args&&... args ); |
(3) | (C++17以降) (C++20 以降 constexpr) |
template< std::size_t I, class U, class... Args > std::variant_alternative_t<I, variant>& |
(4) | (C++17以降) (C++20 以降 constexpr) |
既存のvariantオブジェクト内に新しい値をインプレース(in-place)で作成します。
1)
Types... における T のゼロベースインデックスを I とすると、 emplace<I>(std::forward<Args>(args)...) と同等です。- このオーバーロードは、 std::is_constructible_v<T, Args...> が true であり、かつ
TがTypes...内にちょうど1回だけ現れる場合にのみ、オーバーロード解決に参加します。
2)
Types... における T のゼロベースインデックスを I とすると、 emplace<I>(il, std::forward<Args>(args)...) と同等です。- このオーバーロードは、 std::is_constructible_v<T, std::initializer_list<U>&, Args...> が true であり、かつ
TがTypes...内にちょうど1回だけ現れる場合にのみ、オーバーロード解決に参加します。
3) まず、現在保持されている値(もしあれば)を破棄します。次に、引数 std::forward<Args>(args)... を用いて
T_I 型の値を構築するかのように、保持される値を直接初期化します。例外がスローされた場合、*this は valueless_by_exception になる可能性があります。- このオーバーロードは、 std::is_constructible_v<T_I, Args...> が true である場合にのみ、オーバーロード解決に参加します。
Iが sizeof...(Types) より小さい値でない場合、コンパイル時エラーとなります。
4) まず、現在保持されている値(もしあれば)を破棄します。次に、引数
il および std::forward<Args>(args)... を用いて T_I 型の値を構築するかのように、保持される値を直接初期化します。例外がスローされた場合、*this は valueless_by_exception になる可能性があります。- このオーバーロードは、 std::is_constructible_v<T_I, std::initializer_list<U>&, Args...> が true である場合にのみ、オーバーロード解決に参加します。
Iが sizeof...(Types) より小さい値でない場合、コンパイル時エラーとなります。
目次 |
[編集] パラメータ
| args | - | 新しい値を構築する際に使用するコンストラクタ引数 |
| il | - | 新しい値を構築する際に使用する initializer_list 引数 |
[編集] 戻り値
新しく格納された値への参照。
[編集] 例外
1-4) 格納される値の初期化中にスローされた例外。
[編集] 注記
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_variant |
202106L |
(C++20) (DR) |
完全 constexpr std::variant (1-4) |
[編集] 例
このコードを実行
#include <iostream> #include <string> #include <variant> int main() { std::variant<std::string> v1; v1.emplace<0>("abc"); // OK std::cout << std::get<0>(v1) << '\n'; v1.emplace<std::string>("def"); // OK std::cout << std::get<0>(v1) << '\n'; std::variant<std::string, std::string> v2; v2.emplace<1>("ghi"); // OK std::cout << std::get<1>(v2) << '\n'; // v2.emplace<std::string>("abc"); -> Error }
出力
abc def ghi
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| P2231R1 | C++20 | C++20 では必要な操作が constexpr にできるにもかかわらず、 emplace は constexpr ではありませんでした。 |
constexprではありませんでした。 |
[編集] 関連項目
variant を代入する(public member function) |