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
Определено в заголовочном файле <type_traits>
template < class From, class To >
struct is_convertible ;
(1) (начиная с C++11)
template < class From, class To >
struct is_nothrow_convertible ;
(2) (начиная с C++20)
1) Если определение воображаемой функции To test ( ) { return std:: declval < From > ( ) ; } является корректным (то есть либо std:: declval < From > ( ) может быть преобразовано в To с использованием неявных преобразований , либо и From , и To являются возможно cv-квалифицированным void ), предоставляет константу-член value равную true . В противном случае value равна false . Для целей этой проверки использование std::declval в операторе return не считается ODR-использованием .

Если To является ссылочным типом и при связывании std:: declval < From > ( ) с To будет создан временный объект , оператор return в воображаемой функции считается корректным, даже если такое связывание некорректно в реальной функции.

(since C++26)
Access checks выполняются так, как если бы они происходили из контекста, не связанного ни с одним из типов. Учитывается только валидность непосредственного контекста выражения в операторе return (включая преобразования к возвращаемому типу).
2) То же, что и (1) , но преобразование также noexcept .

Если From или To не являются полными типами, (возможно, cv-квалифицированным) void , или массивом неизвестной границы, поведение не определено.

Если создание экземпляра шаблона выше зависит, прямо или косвенно, от неполного типа, и это создание экземпляра может дать другой результат, если бы этот тип был гипотетически завершен, поведение не определено.

Если программа добавляет специализации для любых шаблонов, описанных на этой странице, поведение не определено.

Содержание

Шаблон вспомогательной переменной

template < class From, class To >
constexpr bool is_convertible_v = is_convertible < From, To > :: value ;
(начиная с C++17)
template < class From, class To >
constexpr bool is_nothrow_convertible_v = is_nothrow_convertible < From, To > :: value ;
(начиная с C++20)

Наследуется от std:: integral_constant

Константы-члены

value
[static]
true если From преобразуем в To , false иначе
(публичная статическая константа-член)

Функции-члены

operator bool
преобразует объект в bool , возвращает value
(публичная функция-член)
operator()
(C++14)
возвращает value
(публичная функция-член)

Типы-члены

Тип Определение
value_type bool
type std:: integral_constant < bool , value >

Возможная реализация

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 {};

Примечания

Дает четко определенные результаты для ссылочных типов, void-типов, массивов и функциональных типов.

В настоящее время стандарт не уточняет, считается ли уничтожение объекта, созданного преобразованием (либо результирующего объекта, либо временного объекта, привязанного к ссылке), частью преобразования. Это описано в LWG issue 3400 .

Все известные реализации рассматривают уничтожение как часть преобразования, как предложено в P0758R1 .

Макрос тестирования возможностей Значение Стандарт Функция
__cpp_lib_is_nothrow_convertible 201806L (C++20) std::is_nothrow_convertible

Пример

#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*>);
    // Обратите внимание, что конструктор Perfect Forwarding делает класс E
    // "конвертируемым" из всего. Таким образом, A может быть заменен на 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';
}

Вывод:

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

Смотрите также

(C++11)
проверяет, является ли один тип базовым для другого типа
(шаблон класса)
проверяет, является ли тип pointer-interconvertible (начальным) базовым классом другого типа
(шаблон класса)
проверяет, являются ли объекты типа pointer-interconvertible с указанным подобъектом этого типа
(шаблон функции)
указывает, что тип может быть неявно преобразован в другой тип
(концепт)