Namespaces
Variants

std:: is_convertible, std:: is_nothrow_convertible

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Definido en el 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)
1) Si la definición de función imaginaria To test ( ) { return std:: declval < From > ( ) ; } está bien formada (es decir, si std:: declval < From > ( ) puede convertirse a To usando conversiones implícitas , o si tanto From como To son posiblemente calificados cv como void ), proporciona la constante miembro value igual a true . De lo contrario, value es false . Para los propósitos de esta verificación, el uso de std::declval en la sentencia return no se considera un uso ODR .

Si To es un tipo referencia y se crearía un objeto temporal al enlazar std:: declval < From > ( ) a To , la sentencia return en la función imaginaria se considera bien formada, aunque dicho enlace esté mal formado en una función real.

(desde C++26)
Access checks se realizan como si fuera desde un contexto no relacionado con ninguno de los tipos. Solo se considera la validez del contexto inmediato de la expresión en la sentencia return (incluyendo conversiones al tipo de retorno).
2) Igual que (1) , pero la conversión también es noexcept .

Si From o To no es un tipo completo, (posiblemente calificado con cv) void , o un array de límite desconocido, el comportamiento es indefinido.

Si una instanciación de una plantilla anterior depende, directa o indirectamente, de un tipo incompleto, y esa instanciación podría producir un resultado diferente si ese tipo se completara hipotéticamente, el comportamiento no está definido.

Si el programa añade especializaciones para cualquiera de las plantillas descritas en esta página, el comportamiento no está definido.

Contenidos

Plantilla de variable auxiliar

template < class From, class To >
constexpr bool is_convertible_v = is_convertible < From, To > :: value ;
(desde C++17)
template < class From, class To >
constexpr bool is_nothrow_convertible_v = is_nothrow_convertible < From, To > :: value ;
(desde C++20)

Heredado de std:: integral_constant

Constantes miembro

value
[static]
true si From es convertible a To , false en caso contrario
(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 >

Implementación posible

is_convertible (1)
namespace detail
{
    template<class T>
    auto test_returnable(int) -> decltype(
        void(static_cast<T(*)()>(nullptr)), std::true_type{}
    );
    template<class>
    auto test_returnable(...) -> std::false_type;
    template<class From, class To>
    auto test_implicitly_convertible(int) -> decltype(
        void(std::declval<void(&)(To)>()(std::declval<From>())), std::true_type{}
    );
    template<class, class>
    auto test_implicitly_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_implicitly_convertible<From, To>(0))::value) ||
    (std::is_void<From>::value && std::is_void<To>::value)
> {};
is_nothrow_convertible (2)
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 {};

Notas

Proporciona resultados bien definidos para tipos de referencia, tipos void, tipos array y tipos de 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 como parte de la conversión. Esto es LWG issue 3400 .

Todas las implementaciones conocidas tratan la destrucción como parte de la conversión, como se propone en P0758R1 .

Macro de prueba de características Valor Estándar Característica
__cpp_lib_is_nothrow_convertible 201806L (C++20) std::is_nothrow_convertible

Ejemplo

#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#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; };
    static_assert(std::is_convertible_v<B*, A*>);
    static_assert(!std::is_convertible_v<A*, B*>);
    static_assert(std::is_convertible_v<D, C>);
    static_assert(!std::is_convertible_v<B*, C*>);
    // Note que el constructor de Perfect Forwarding hace que la clase E sea
    // "convertible" desde todo. Por lo tanto, A es reemplazable por B, C, D..:
    static_assert(std::is_convertible_v<A, E>);
    static_assert(!std::is_convertible_v<std::string_view, std::string>);
    static_assert(std::is_convertible_v<std::string, std::string_view>);
    auto stringify = []<typename T>(T x)
    {
        if constexpr (std::is_convertible_v<T, std::string> or
                      std::is_convertible_v<T, std::string_view>)
            return x;
        else
            return std::to_string(x);
    };
    using std::operator "" s, std::operator "" sv;
    const char* three = "three";
    std::cout << std::quoted(stringify("one"s)) << ' '
              << std::quoted(stringify("two"sv)) << ' '
              << std::quoted(stringify(three)) << ' '
              << std::quoted(stringify(42)) << ' '
              << std::quoted(stringify(42.0)) << '\n';
}

Salida:

"one" "two" "three" "42" "42.000000"

Véase también

(C++11)
verifica si un tipo es una base de otro tipo
(class template)
verifica si un tipo es una base pointer-interconvertible (inicial) de otro tipo
(class template)
verifica si los objetos de un tipo son pointer-interconvertible con el subobjeto especificado de ese tipo
(function template)
especifica que un tipo es implícitamente convertible a otro tipo
(concept)