std::is_convertible, std::is_nothrow_convertible - cppreference.com

From cppreference.com

Defined in header

<type_traits>

template<classFrom,classTo>structis_convertible; (1)(since C++11)template<classFrom,classTo>structis_nothrow_convertible; (2)(since C++20)1) If the imaginary function definition Totest(){returnstd::declval<From>();} is well-formed, (that is, either std::declval<From>() can be converted to To using

implicit conversions

, or both From and To are possibly cv-qualified void), provides the member constant value equal to true. Otherwise value is false. For the purposes of this check, the use of

std::declval

in the return statement is not considered an

ODR-use

.

If To is a reference type and a

temporary object

would be created when binding std::declval<From>() to To, the return statement in the imaginary function is considered well-formed, even though such binding is ill-formed in an actual function.

(since C++26)

Access checks

are performed as if from a context unrelated to either type. Only the validity of the immediate context of the expression in the return statement (including conversions to the return type) is considered.

2) Same as (1), but the conversion is also noexcept.

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

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 behavior is undefined.

If the program adds specializations for any of the templates described on this page, the behavior is undefined.

Helper variable template

template<classFrom,classTo>constexprboolis_convertible_v=is_convertible<From,To>::value;(since C++17)template<classFrom,classTo>constexprboolis_nothrow_convertible_v=is_nothrow_convertible<From,To>::value;(since C++20)Inherited from

std::integral_constant

Member constants

value

[static]

true if From is convertible to To, false otherwise
(public static member constant)Member functions

operator bool

converts the object to bool, returns value
(public member function)operator()

(C++14)

returns value
(public member function)Member types

Type Definition value_typebooltypestd::integral_constant<bool,value>Possible implementation

is_convertible (1)

namespacedetail{template<classT>autotest_returnable(int)->decltype(void(static_cast<T(*)()>(nullptr)),std::true_type{});template<class>autotest_returnable(...)->std::false_type;template<classFrom,classTo>autotest_implicitly_convertible(int)->decltype(void(std::declval<void(&)(To)>()(std::declval<From>())),std::true_type{});template<class,class>autotest_implicitly_convertible(...)->std::false_type;}// namespace detailtemplate<classFrom,classTo>structis_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<classFrom,classTo>structis_nothrow_convertible:std::conjunction<std::is_void<From>,std::is_void<To>>{};template<classFrom,classTo>requiresrequires{static_cast<To(*)()>(nullptr);{std::declval<void(&)(To)noexcept>()(std::declval<From>())}noexcept;}structis_nothrow_convertible<From,To>:std::true_type{};Notes

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

Currently the standard has not specified whether the destruction of the object produced by the conversion (either a result object or a temporary bound to a reference) is considered as a part of the conversion. This is

LWG issue 3400

.

All known implementations treat the destruction as a part of the conversion, as proposed in

P0758R1

.

Feature-test

macroValueStdFeature

__cpp_lib_is_nothrow_convertible

201806L

(C++20)std::is_nothrow_convertibleExample

Run this code

#include<iomanip>#include<iostream>#include<string>#include<string_view>#include<type_traits>usingnamespacestd::literals;classA{};classB:publicA{};classC{};classD{public:operatorC(){returnc;}Cc;};classE{public:template<classT>E(T&&){}};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>);intmain(){autostringify=[]<typenameT>(Tx){ifconstexpr(std::is_convertible_v<T,std::string>orstd::is_convertible_v<T,std::string_view>)returnstd::quoted(x);elsereturnstd::to_string(x);};constchar*three="three";std::cout<<stringify("one"s)<<' '<<stringify("two"sv)<<' '<<stringify(three)<<' '<<stringify(42)<<' '<<stringify(42.24)<<'\n';}Possible output:

"one" "two" "three" 42 42.24 See also