Expected<T>se implementa en llvm / Support / Error.h. Es una unión etiquetada que tiene una To una Error.
Expected<T>es una clase de plantilla con tipo T:
template <class T> class LLVM_NODISCARD Expected
Pero estos dos constructores realmente me confunden:
/// 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));
}
¿Por qué Expected<T>repite dos construcciones para la misma implementación? ¿Por qué no lo hace así?
template <class OtherT>
Expected(Expected<OtherT>&& Other) { moveConstruct(std::move(Other));}

explicitpalabra claveexplicitpalabras clave son importantes aquí. ¿Alguien podría dar un ejemplo?Respuestas:
Porque ese constructor es condicionalmente explícito de acuerdo con la propuesta. Esto significa que el constructor es explícito solo si se cumple alguna condición (aquí, convertibilidad de
TyOtherT).C ++ no tiene un mecanismo para esta funcionalidad (algo así como
explicit(condition)) antes de C ++ 20. Por lo tanto, las implementaciones deben usar algún otro mecanismo, como la definición de dos constructores diferentes , uno explícito y otro de conversión , y garantizar la selección del constructor adecuado de acuerdo con la condición. Esto normalmente se realiza a través de SFINAE con la ayuda destd::enable_if, donde se resuelve la condición.Desde C ++ 20, debe haber una versión condicional del
explicitespecificador. La implementación sería mucho más fácil con una sola definición:fuente
Para entender esto debemos comenzar con
std::is_convertible. Según cppreference :La parte importante aquí es que solo busca conversiones implícitas. Por lo tanto, lo que significan las dos implementaciones en su OP es que si
OtherTes implícitamente convertible aT, entoncesexpected<OtherT>es implícitamente convertible aexpected<T>. SiOtherTrequiere una conversión explícita aT, entoncesExpected<OtherT>requiere y una conversión explícita aExpected<T>.Aquí hay ejemplos de modelos implícitos y explícitos y sus
Expectedhomólogos.fuente
Expected<OtherT>requiere un reparto explícito paraExpected<T>significar'. ¿Qué significa el "reparto explícito" aquí? No puedo imaginar un ejemplo para esto.