std::is_convertible, std::is_nothrow_convertible
Definido en el archivo de encabezado <type_traits> | ||
template<class From, class To > struct is_convertible; | (1) | (desde C++11) |
template<class From, class To > struct is_nothrow_convertible; | (2) | (desde C++20) |
To
usando conversiones implícitas, o tanto From
como To
están posiblemente calificadas-cv void
), proporciona la constante miembro value
igual a true. De lo contrario, value
es false. A efectos de esta comprobación, el uso de std::declval en la instrucción return no se considera un uso ODR.noexcept
.From
y To
deberá cada uno ser un tipo completo, (posiblemente calificado-cv) void, o un array de límite desconocido. De lo contrario, el comportamiento está indefinido.
Si la instanciación de una plantilla anterior depende, directa o indirectamente, de un tipo incompleto, y esa instanciación podría generar un resultado distinto si ese tipo hipotéticamente se completara, el comportamiento está indefinido.
El comportamiento de un programa que añade especializaciones para cualquiera de las plantillas definidas en esta página no está definido.
Contenido |
[editar]Plantilla de variable auxiliar
template<class From, class To > inlineconstexprbool is_convertible_v = is_convertible<From, To>::value; | (desde C++17) | |
template<class From, class To > inlineconstexprbool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value; | (desde C++20) | |
Heredado de std::integral_constant
Constantes miembro
value [estático] | true si From is convertible to To , de lo contrario false. (constante miembro pública estática) |
Funciones miembro
operator bool | Convierte el objeto a bool, devuelve value . (función miembro pública) |
operator() (C++14) | Devuelve value . (función miembro pública) |
Tipos miembro
Tipo | Definición |
value_type | bool |
type | std::integral_constant<bool, value> |
[editar]Posible implementación
Primera versión |
---|
namespace detail { template<class>using true_type_for =std::true_type; template<class T>auto test_returnable(int)-> true_type_for<T()>;template<class>auto test_returnable(...)->std::false_type; template<class From, class To>auto test_nonvoid_convertible(int)-> true_type_for< decltype(std::declval<void(&)(To)>()(std::declval<From>()))>;template<class, class>auto test_nonvoid_convertible(...)->std::false_type; }// namespace detail template<class From, class To>struct is_convertible :std::integral_constant<bool, (decltype(detail::test_returnable<To>(0))::value&& decltype(detail::test_nonvoid_convertible<From, To>(0))::value)||(std::is_void<From>::value&&std::is_void<To>::value)>{}; |
Segunda versión |
template<class From, class To>struct is_nothrow_convertible :std::conjunction<std::is_void<From>, std::is_void<To>>{}; template<class From, class To> requires requires {static_cast<To(*)()>(nullptr);{std::declval<void(&)(To)noexcept>()(std::declval<From>())}noexcept;}struct is_nothrow_convertible<From, To>:std::true_type{}; |
[editar]Notas
Da resultados bien definidos para tipos referencia, tipos void, tipos array, y tipos función.
Actualmente, el estándar no ha especificado si la destrucción del objeto producido por la conversión (ya sea un objeto resultado o un temporal vinculado a una referencia) se considera una parte de la conversión. Este es el problema LWG 3400.
Todas las implementaciones conocidas tratan la destrucción como parte de la conversión, como se propone en P0758R1.
[editar]Ejemplo
#include <iostream>#include <type_traits> class E {public:template<class T> E(T&&){}}; int main(){class A {};class B :public A {};class C {};class D {public: operator C(){return c;} C c;}; bool b2a = std::is_convertible<B*, A*>::value;bool a2b = std::is_convertible<A*, B*>::value;bool b2c = std::is_convertible<B*, C*>::value;bool d2c = std::is_convertible<D, C>::value; // Un contructor de reenvío perfecto hace que la clase se 'convierta' desde todo bool everything2e = std::is_convertible<A, E>::value;//< B, C, D, etc std::cout<<std::boolalpha; std::cout<< b2a <<'\n';std::cout<< a2b <<'\n';std::cout<< b2c <<'\n';std::cout<< d2c <<'\n';std::cout<<'\n';std::cout<< everything2e <<'\n';}
Salida:
true false false true true