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 > ( ) ; } が well-formed である場合(つまり、 std:: declval < From > ( ) 暗黙変換 を使用して To に変換可能であるか、あるいは From To の両方が possibly cv-qualified void である場合)、メンバー定数 value true に設定する。それ以外の場合、 value false となる。このチェックの目的において、return 文内での std::declval の使用は ODR-use とは見なされない。

To が参照型であり、 std:: declval < From > ( ) To にバインドする際に 一時オブジェクト が作成される場合、実際の関数ではそのようなバインドは ill-formed であるが、仮想関数内の return 文は well-formed と見なされる。

(C++26以降)
Access checks は、いずれの型とも無関係なコンテキストから実行されるかのように行われます。return文内の式の直接的なコンテキスト(戻り値の型への変換を含む)の妥当性のみが考慮されます。
2) (1) と同様ですが、変換は noexcept でもあります。

From または To が完全型でない場合、(修飾された可能性のある) 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*>);
    // 完全転送コンストラクタにより、クラス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)
ある型が別の型の基底クラスであるかどうかをチェックする
(クラステンプレート)
ある型が別の型の ポインター相互変換可能 な(初期)基底クラスであるかどうかをチェックする
(クラステンプレート)
ある型のオブジェクトが、その型の指定されたサブオブジェクトと ポインター相互変換可能 であるかどうかをチェックする
(関数テンプレート)
ある型が別の型に暗黙的に変換可能であることを指定する
(コンセプト)