名前空間
変種
操作

std::is_convertible, std::is_nothrow_convertible

From cppreference.com
< cpp‎ | types
 
 
メタプログラミングライブラリ
型特性
型のカテゴリ
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
型のプロパティ
(C++11)
(C++11)
(C++14)
(C++11)(C++26で非推奨)
(C++11)(C++20まで*)
(C++11)(C++20で非推奨)
(C++11)
型特性定数
メタ関数
(C++17)
サポートされている操作
関係とプロパティクエリ
型の変更
(C++11)(C++11)(C++11)
型の変換
(C++11)(C++23で非推奨)
(C++11)(C++23で非推奨)
(C++11)
(C++11)(C++20まで*)(C++17)

(C++11)
(C++17)
コンパイル時有理数演算
コンパイル時整数シーケンス
 
ヘッダ <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 に変換できるか、あるいは FromTo の両方がcv修飾されたvoidである)である場合、trueに等しいメンバ定数valueを提供する。そうでない場合、valuefalseである。このチェックの目的のため、return文におけるstd::declvalの使用は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]
FromToに変換可能であればtrue、そうでなければfalse
(公開静的メンバ定数)

メンバ関数

operator bool
オブジェクトを bool に変換し、value を返します。
(public member function)
operator()
(C++14)
value を返します。
(public member function)

メンバ型

定義
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*>);
    // 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"

[編集] 関連項目

ある型が他の型の基底であるかをチェックする
(クラステンプレート) [編集]
ある型が他の型のポインタ相互変換可能な(初期)基底であるかをチェックする
(クラステンプレート) [編集]
ある型のオブジェクトが、その型の指定されたサブオブジェクトとポインタ相互変換可能であるかをチェックする
(関数テンプレート) [編集]
型が別の型に暗黙的に変換可能であることを規定する
(コンセプト) [編集]
English 日本語 中文(简体) 中文(繁體)