std::unexpected 构造函数约束

std::unexpected constructor constraint

提问人:NotMe 提问时间:3/18/2023 最后编辑:NotMe 更新时间:3/19/2023 访问量:199

问:

我正在阅读 cpp 23 标准,我偶然发现了.std::unexpected

节 expected.un.cons 定义

template<class Err = E>
constexpr explicit unexpected(Err&& e);

具有以下成本(除其他外)

is_same_v<remove_cvref_t<Err>, unexpected> is false; 

鉴于类模板是意外的,这个表达式什么时候是正确的?

C++ C++23 标准预期

评论


答:

9赞 user17732522 3/18/2023 #1

unexpected是类模板作用域中的注入类名。它指的是模板的当前专业化。它不引用模板本身,因为相同的名称将在类范围之外引用。

例如,如果你将

template<typename T>
struct X {
    static X x;
};

则类型为 。您不必在声明中重复模板参数列表。如果没有给出,则解析为 injected-class-name,它引用具有相同模板参数列表的模板的当前专用化。X<T>::xX<T>x

约束的存在使得在重载解析中不能选择构造函数而不是复制构造函数,否则对于非左值参数可能会发生这种情况。const

评论

0赞 NotMe 3/19/2023
你是说移动构造函数(非常量左值)吗?我正在尝试使用此代码,但我看不到约束 godbolt.org/z/s3MnE3463 的效果
1赞 user17732522 3/19/2023
@NikBomb 不,我的意思是没有 .请参见 godbolt.org/z/q691Y6arostd::move
0赞 NotMe 3/19/2023
我明白了,谢谢!为什么在包装器/一元类型的情况下应该首选复制构造函数,有什么特殊的原因吗?我看到做了类似的事情。std::optional
1赞 user17732522 3/19/2023
@NikBomb 转发构造函数尝试使用参数初始化包含的对象(类型为 )。通常不能从 .如果具有来自 的构造函数,它将无法编译或可能具有错误的语义。复制构造函数应该复制整体,而不影响它的细节。EEunexpected<E>Eunexpected<E>unexpected<E>E