Spec-Zone.ru › C++

std::is_convertible, std::is_nothrow_convertible

Определено в заголовочном файле <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 в мнимой функции считается корректным, хотя такая привязка некорректна в реальной функции.

(начиная с C++26)
Проверки доступа выполняются так, как если бы они производились из контекста, не связанного ни с одним из типов. Рассматривается только корректность непосредственного контекста выражения в операторе 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 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*>);
    // Note that the Perfect Forwarding constructor makes the class E be
    // "convertible" from everything. So, A is replaceable by 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"

См. также

is_base_of
(C++11)
проверяет, является ли один тип базовым для другого типа
(шаблон класса)
is_pointer_interconvertible_base_of
(C++20)
проверяет, является ли тип взаимно преобразуемой по указателю (начальной) базой другого типа
(шаблон класса)
is_pointer_interconvertible_with_class
(C++20)
проверяет, являются ли объекты типа взаимно преобразуемыми по указателю с указанным подобъектом этого типа
(шаблон функции)
convertible_to
(C++20)
задает требование, согласно которому тип неявно преобразуется в другой тип
(концепт)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/types/is_convertible

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API