std::unexpected
来自cppreference.com
<tbody>
</tbody>
| 在标头 <expected> 定义
|
||
template< class E > class unexpected; |
(C++23 起) | |
类模板 std::unexpected 代表一个 std::expected 中存储的非预期值。特别地,std::expected 具有接受 std::unexpected 为唯一实参的构造函数,创建含有非预期值的 expected 对象。
用非对象类型、数组类型、std::unexpected 的特化或有 cv 限定的类型实例化 unexpected 的程序非良构。
模板形参
| E | - | 非预期值的类型。该类型不能是数组类型、非对象类型、std::unexpected 的特化或有 cv 限定的类型
|
成员函数
构造 unexpected 对象 (公开成员函数) | |
(析构函数) (隐式声明) |
销毁 unexpected 对象以及其中存储的值 (公开成员函数) |
operator= (隐式声明) |
向存储的值赋值 (公开成员函数) |
| 访问存储的值 (公开成员函数) | |
| 交换存储的值 (公开成员函数) |
非成员函数
(C++23) |
比较存储的值 (函数模板) |
(C++23) |
特化 std::swap 算法 (函数模板) |
std::unexpected::unexpected
<tbody> </tbody> 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( std::in_place_t, Args&&... args ); |
(4) | |
template< class U, class... Args > constexpr explicit unexpected( std::in_place_t, std::initializer_list<U> il, Args&&... args ); |
(5) | |
构造 std::unexpected 对象。
1,2) 复制/移动构造函数。分别复制或移动存储的值。
3) 如同从
std::forward<Err>(e) 直接初始化一个 E 类型的值一样构造存储的值。
- 此重载只有在
std::is_same_v<std::remove_cvref_t<Err>, unexpected>为false,且std::is_same_v<std::remove_cvref_t<Err>, std::in_place_t>为false,且std::is_constructible_v<E, Err>为true
4) 如同从
std::forward<Args>(args)... 直接初始化一个 E 类型的值一样构造存储的值。
- 此重载只有在
std::is_constructible_v<E, Args...>为true时才会参与重载决议。
5) 如同从
il, std::forward<Args>(args)... 直接初始化一个 E 类型的值一样构造存储的值。
- 此重载只有在
std::is_constructible_v<E, std::initializer_list<U>&, Args...>为true时才会参与重载决议。
参数
| e | - | 初始化所含值所用的值 |
| args... | - | 初始化所含值所用的实参 |
| il | - | 初始化所含值所用的初始化式列表 |
异常
抛出任何 E 的构造函数所抛的异常。
std::unexpected::error
<tbody> </tbody> constexpr const E& error() const& noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const&& noexcept; constexpr E&& error() && noexcept; |
||
返回到存储的值的引用。
std::unexpected::swap
<tbody> </tbody> constexpr void swap( unexpected& other ) noexcept(std::is_nothrow_swappable_v<E>); |
||
如同 using std::swap; swap(error(), other.error()); 一样交换存储的值。
如果 std::is_swappable_v<E> 为 false,程序非良构。
operator==(std::unexpected)
<tbody> </tbody> template< class E2 > friend constexpr bool operator==( unexpected& x, std::unexpected<E2>& y ); |
||
如同 return x.error() == y.error() 一样比较存储的值。
如果表达式 x.error() == e.error() 非良构,或其结果不能转换到 bool,则程序非良构。
此函数对常规的无限定或有限定查找不可见,而只能在 std::unexpected<E> 为实参的关联类时由实参依赖查找找到。
swap(std::unexpected)
<tbody> </tbody> friend constexpr void swap( unexpected& x, unexpected& y ) noexcept(noexcept(x.swap(y))); |
||
等价于 x.swap(y)。
此重载只有在 std::is_swappable_v<E> 为 true 时才会参与重载决议。
此函数对常规的无限定或有限定查找不可见,而只能在 std::unexpected<E> 为实参的关联类时由实参依赖查找找到。
推导指引
<tbody> </tbody> template< class E > unexpected(E) -> unexpected<E>; |
(C++23 起) | |
为 unexpected 提供推导指引以允许从构造函数实参推导。
注解
在 C++17 前,名字 std::unexpected 指代 C++ 运行时在违背动态异常规范时调用的函数。
示例
运行此代码
#include <expected>
#include <iostream>
enum class error
{
compile_time_error,
runtime_error
};
[[nodiscard]] auto unexpected_runtime_error() -> std::expected<int, error>
{
return std::unexpected(error::runtime_error);
}
int main()
{
std::expected<double, int> ex = std::unexpected(3);
if (!ex)
std::cout << "ex 包含错误值\n";
if (ex == std::unexpected(3))
std::cout << "错误值等于 3\n";
const auto e = unexpected_runtime_error();
e.and_then([](const auto& e) -> std::expected<int, error>
{
std::cout << "and_then: " << int(e); // 不打印
return {};
})
.or_else([](const auto& e) -> std::expected<int, error>
{
std::cout << "or_else: " << int(e); // 打印此行
return {};
});
}
输出:
ex 包含错误值
错误值等于 3
or_else: 1
参阅
构造 expected 对象 (公开成员函数) | |
(C++23) |
比较 expected 对象 (函数模板) |