constexpr unexpected(const unexpected&) = default; // (1)
constexpr unexpected(unexpected&&) = default; // (2)
template<class Err = E>
constexpr explicit unexpected(Err&& e); // (3)
template<class... Args>
constexpr explicit unexpected(in_place_t, Args&&... args); // (4)
template<class U, class... Args>
constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args); // (5)
概要
- (1) : コピーコンストラクタ。
- (2) : ムーブコンストラクタ。
- (3) : 変換可能な
Err
オブジェクトからコピー/ムーブ構築する。 - (4) : コンストラクタ引数として任意個の引数を受け取って、コンストラクタ内で型
E
のオブジェクトを生成し、保持する。 - (5) : コンストラクタ引数として初期化子リストと任意個の引数を受け取って、コンストラクタ内で型
E
のオブジェクトを生成し、保持する。
テンプレートパラメータ制約
- (3) : 次の制約を全て満たすこと
is_same_v<remove_cvref_t<Err>, unexpected> == false
is_same_v<remove_cvref_t<Err>, in_place_t> == false
is_constructible_v<E, Err> == true
- (4) :
is_constructible_v<E, Args...> == true
- (5) :
is_constructible_v<E, initializer_list<U>&, Args...> == true
効果
- (3) :
std::forward<Err>(e)
でエラー値を直接非リスト初期化する。 - (4) :
std::forward<Args>(args)...
でエラー値を直接非リスト初期化する。 - (5) :
il, std::forward<Args>(args)...
でエラー値を直接非リスト初期化する。
例外
型E
の初期化から送出される例外。
例
#include <cassert>
#include <expected>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
// std::pair型から2要素std::tuple型へはコピー変換可能
using IntPair = std::pair<int, int>;
using IntTuple = std::tuple<int, int>;
// std::unique_ptr型からstd::shared_ptr型へはムーブ変換可能
using UniquePtr = std::unique_ptr<int>;
using SharedPtr = std::shared_ptr<int>;
// 引数リスト または 初期化子リスト+引数リスト から構築可能な型
struct ComplexType {
std::string data;
std::vector<int> seq;
ComplexType(const char* ptr, size_t len)
: data(ptr, len) {}
ComplexType(std::initializer_list<int> il, std::string_view sv)
: data(sv), seq(il) {}
};
int main()
{
// (1) コピーコンストラクタ
{
std::unexpected<int> src{42};
std::unexpected<int> dst = src;
assert(src.error() == 42 && dst.error() == 42);
}
// (2) ムーブコンストラクタ
{
std::unexpected<std::string> src{"Oops!"};
std::unexpected<std::string> dst = std::move(src);
assert(dst.error() == "Oops!");
// src.error()はstd::stringムーブ後の未規定の値
}
// (3) 変換コピー構築
{
IntPair src = {1, 2};
std::unexpected<IntTuple> dst{src};
assert((dst.error() == IntTuple{1, 2}));
}
// (3) 変換ムーブ構築
{
UniquePtr src = std::make_unique<int>(42);
std::unexpected<SharedPtr> dst{std::move(src)};
assert(*dst.error() == 42);
assert(src == nullptr);
// ムーブ後のstd::unique_ptr型はnullptrが保証される
}
// (4),(5) 引数リストから直接構築
{
std::unexpected<ComplexType> x1{std::in_place, "C++", 1};
assert(x1.error().data == "C");
// "C++"より長さ1の文字列が構築されている
std::unexpected<ComplexType> x2{std::in_place, {98, 11, 23}, "C++"};
assert(x2.error().data == "C++");
assert((x2.error().seq == std::vector<int>{98, 11, 23}));
}
}
xxxxxxxxxx
#include <cassert>
#include <expected>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
// std::pair型から2要素std::tuple型へはコピー変換可能
using IntPair = std::pair<int, int>;
using IntTuple = std::tuple<int, int>;
// std::unique_ptr型からstd::shared_ptr型へはムーブ変換可能
using UniquePtr = std::unique_ptr<int>;
using SharedPtr = std::shared_ptr<int>;
// 引数リスト または 初期化子リスト+引数リスト から構築可能な型
出力
バージョン
言語
- C++23
処理系
- Clang: 16.0 ✅
- GCC: 12.1 ✅
- ICC: ??
- Visual C++: ??