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 в операторе возврата не считается odr-использованием.
Проверки доступа выполняются так, как будто из контекста, не связанного ни с одним типом. Рассматривается только корректность непосредственного контекста выражения в операторе возврата (включая преобразования к типу возвращаемого значения).
2) То же, что и (1), но преобразование также noexcept.

From и To должны быть полными типами (возможно, cv-квалифицированными), void или массивом неизвестной длины. В противном случае поведение не определено.

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

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

Вспомогательный шаблон переменной

template< class From, class To >
inline constexpr bool is_convertible_v = is_convertible<From, To>::value;
(с C++17)
template< class From, class To >
inline 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>

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

(1) is_convertible
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)
> {};
(2) is_nothrow_convertible
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.

Макрос проверки наличия функции Значение Std Функция
__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; };
 
    std::cout
        << std::boolalpha
        << std::is_convertible_v<B*, A*> << ' ' // true
        << std::is_convertible_v<A*, B*> << ' ' // false
        << std::is_convertible_v<D, C> << ' '   // true
        << std::is_convertible_v<B*, C*> << ' ' // false
        // Note that the Perfect Forwarding constructor makes the class E be
        // "convertible" from everything. So, A is replaceable by B, C, D..:
        << std::is_convertible_v<A, E> << ' ';  // true
 
    using std::operator "" s, std::operator "" sv;
 
    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);
    };
 
    const char* three = "three";
 
    std::cout
        << std::is_convertible_v<std::string_view, std::string> << ' ' // false
        << std::is_convertible_v<std::string, std::string_view> << ' ' // true
        << std::quoted(stringify("one"s)) << ' '
        << std::quoted(stringify("two"sv)) << ' '
        << std::quoted(stringify(three)) << ' '
        << std::quoted(stringify(42)) << ' '
        << std::quoted(stringify(42.0)) << '\n';
}

Вывод:

true false true false true false true "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/w/cpp/types/is_convertible

Spec-Zone.ru

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