Expected<T>在llvm/Support/Error.h中实现。它是一个有标记的工会,持有T或Error。
Expected<T>是一个具有T类型的模板类。
template <class T> class LLVM_NODISCARD Expected但这两个建设者真的把我搞糊涂了:
/// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
/// must be convertible to T.
template <class OtherT>
Expected(Expected<OtherT> &&Other,
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
* = nullptr) {
moveConstruct(std::move(Other));
}
/// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
/// isn't convertible to T.
template <class OtherT>
explicit Expected(
Expected<OtherT> &&Other,
typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
nullptr) {
moveConstruct(std::move(Other));
}为什么Expected<T>要为相同的实现重复两个构造?为什么它不这样做呢?
template <class OtherT>
Expected(Expected<OtherT>&& Other) { moveConstruct(std::move(Other));}发布于 2019-10-20 08:50:30
因为根据建议,该构造函数是有条件地显式。这意味着只有满足某些条件(这里,T和OtherT的可转换性),构造函数才是显式的。
C++在explicit(condition)之前没有这种功能的机制。因此,实现需要使用其他机制,例如两个不同构造函数的定义--一个是显式的,另一个是转换的--并确保根据条件选择合适的构造函数。这通常是通过SFINAE在std::enable_if的帮助下完成的,在那里条件是被解决的。
从C++20开始,应该有一个explicit说明符的条件版本。那么,用一个定义来实现就容易多了:
template <class OtherT>
explicit(!std::is_convertible_v<OtherT, T>)
Expected(Expected<OtherT> &&Other)
{
moveConstruct(std::move(Other));
}发布于 2019-10-20 08:50:22
要理解这一点,我们应该从std::is_convertible开始。根据优先选择
如果虚函数定义
To test() { return std::declval<From>(); }格式良好(也就是说,可以使用隐式转换将std::declval<From>()转换为To,或者From和To都可能是cv限定的From),则提供等于true的成员常量值。否则值为false。出于本检查的目的,返回语句中使用std::declval不被视为odr-use。 访问检查就像从与任何类型无关的上下文中执行一样。只考虑返回语句中表达式的直接上下文的有效性(包括对返回类型的转换)。
这里重要的部分是它只检查隐式转换。因此,在您的操作中,这两个实现的意思是,如果OtherT隐式地可转换为T,那么expected<OtherT>就隐式地可转换为expected<T>。如果OtherT需要对T的显式强制转换,那么Expected<OtherT>需要并显式地强制转换到Expected<T>。
下面是隐式和显式强制转换及其Expected对应的示例
int x;
long int y = x; // implicit cast ok
Expected<int> ex;
Expected<long int> ey = ex; // also ok
void* v_ptr;
int* i_ptr = static_cast<int*>(v_ptr); // explicit cast required
Expected<void*> ev_ptr;
auto ei_ptr = static_cast<Expected<int*>>(ev_ptr); // also requiredhttps://stackoverflow.com/questions/58471254
复制相似问题