template<class... Args>
constexpr T& emplace(Args&&... args) noexcept; // (1)
template<class U, class... Args>
constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept; // (2)
概要
- (1) : 正常値型
T
のコンストラクタ引数として任意個の引数を受け取って、型T
のオブジェクトを正常値として生成し、保持する。 - (2) : 正常値型
T
のコンストラクタ引数として初期化子リストと任意個の引数を受け取って、型T
のオブジェクトを正常値として生成し、保持する。
動作説明用のexpected
クラスメンバ変数として、下記を導入する。
val
:T
型の正常値。unex
:E
型のエラー値。has_val
:bool
型のフラグ変数。正常値を保持する場合はtrue
に、エラー値を保持する場合はfalse
となる。
テンプレートパラメータ制約
- (1) :
is_nothrow_constructible_v<T, Args...> == true
- (2) :
is_nothrow_constructible_v<T, initializer_list<U>&, Args...> == true
効果
-
(1) : 次の処理と等価
if (has_value()) { destroy_at(addressof(val)); } else { destroy_at(addressof(unex)); has_val = true; } return *construct_at(addressof(val), std::forward<Args>(args)...);
-
(2) : 次の処理と等価
if (has_value()) { destroy_at(addressof(val)); } else { destroy_at(addressof(unex)); has_val = true; } return *construct_at(addressof(val), il, std::forward<Args>(args)...);
例
#include <cassert>
#include <expected>
#include <numeric>
// 引数リスト または 初期化子リスト+引数リスト から例外送出なしに構築可能な型
struct ComplexType {
int result = 0;
ComplexType(int a, int b) noexcept
: result(a + b) {}
ComplexType(std::initializer_list<int> list, int init) noexcept
: result(std::accumulate(list.begin(), list.end(), init)) {}
};
int main()
{
// (1)
{
std::expected<ComplexType, int> x = std::unexpected{0};
x.emplace(1, 2);
assert(x.has_value());
assert(x.value().result == 3);
}
// (2)
{
std::expected<ComplexType, int> x = std::unexpected{0};
x.emplace({1, 2, 3, 4}, 5);
assert(x.has_value());
assert(x.value().result == 15);
}
}
出力
バージョン
言語
- C++23
処理系
- Clang: 16.0 ✅
- GCC: 12.1 ✅
- ICC: ??
- Visual C++: ??