std::meta::is_convertible_type, std::meta::is_nothrow_convertible_type - cppreference.com
Namespaces
Variants

std::meta::is_convertible_type, std::meta::is_nothrow_convertible_type

From cppreference.com
< cpp | meta
 
 
 
Reflection library
 
Reflection types and queries
Type properties
Type property queries
 
Defined in header <meta>
consteval bool is_convertible_type( std::meta::info from,
                                    std::meta::info to );
(1) (since C++26)
consteval bool is_nothrow_convertible_type( std::meta::info from,
                                            std::meta::info to );
(2) (since C++26)

Checks if reflected type From (represented by from) can be converted to the type To (represented by to).

1) Equivalent to return std::is_convertible_v<To, From>;.
2) Equivalent to return std::is_nothrow_convertible_v<To, From>;.

If From or To is not a complete type, (possibly cv-qualified) void, or an array of unknown bound, the program is ill-formed.

If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the program is ill-formed.

Parameters

from, to - reflection values to check

Return value

true if the type From is convertible to the type To as described above. Otherwise, false.

Exceptions

Throws std::meta::exception:

  • If either from or to does not represent a type or type alias.
  • If either From or To does not represent a complete type, (possibly cv-qualified) void, or an array of unknown bound.
  • If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed.

Notes

Gives well-defined results for reference types, void types, array types, and function types.

Example

#include <iomanip>
#include <iostream>
#include <meta>
#include <string>
#include <string_view>
using namespace std::literals;

class A {};
class B : public A {};
class C {};
class D { public: operator C() { return c; } C c; };
class E { public: template<class T> E(T&&) {} };

static_assert(
    is_convertible_type(^^B*, ^^A*) == true and
    is_convertible_type(^^A*, ^^B*) == false and
    is_convertible_type(^^D, ^^C) == true and
    is_convertible_type(^^B*, ^^C*) == false and
    is_convertible_type(^^C, ^^C) == true
);

// Note that the Perfect Forwarding constructor makes the class E be
// “convertible” from everything. So, A is replaceable by B, C, D..:
static_assert(is_convertible_type(^^A, ^^E));

static_assert(!is_convertible_type(^^std::string_view, ^^std::string));
static_assert(is_convertible_type(^^std::string, ^^std::string_view));

int main()
{
    auto stringify = []<typename T>(T x)
    {
        if constexpr (is_convertible_type(^^T, ^^std::string) or
                      is_convertible_type(^^T, ^^std::string_view))
            return std::quoted(x);
        else
            return std::to_string(x);
    };

    std::cout << stringify("one") << ' '
              << stringify("two"s) << ' '
              << stringify("three"sv) << ' '
              << stringify(42) << ' '
              << stringify(42.8) << '\n';
}

Output:

"one" "two" "three" 42 42.8

See also