C++標準ライブラリstd::is_convertible
メタ関数とstd::convertible_to
コンセプトの超微妙な違い。本記事の内容はStackOverflowで見つけた質問と回答に基づく。
要約:
is_convertible<From, To>
メタ関数:From
型からTo
型へ暗黙変換できることを検査する。convertible_to<From, To>
コンセプト:From
型からTo
型へ暗黙変換および明示変換できることを検査する。
暗黙変換は可能だが明示変換が許可されないケースで差異が生じる。ジェネリックライブラリの設計者大変すぎでしょ。
#include <concepts> #include <type_traits> struct From; struct To { To() = default; // From→Toの明示変換を禁止 explicit To(From) = delete; }; struct From { // From→Toの暗黙変換は許可 operator To() { return {}; } }; static_assert( std::is_convertible_v<From, To> ); static_assert( !std::convertible_to<From, To> ); To to1 = From{}; // OK: 暗黙変換 To to2{From{}}; // NG: 明示変換
C++20(N4861) 18.4.4/p1, 20.15.6/p5より引用(下線部は強調)。
Given types
From
andTo
and an expressionE
such thatdecltype((E))
isadd_rvalue_reference_t<From>
,convertible_to<From, To>
requiresE
to be both implicitly and explicitly convertible to typeTo
. The implicit and explicit conversions are required to produce equal results.template<class From, class To> concept convertible_to = is_convertible_v<From, To> && requires(add_rvalue_reference_t<From> (&f)()) { static_cast<To>(f()); };
The predicate condition for a template specialization
is_convertible<From, To>
shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:To test() { return declval<From>(); }
[Note: This requirement gives well-defined results for reference types, void types, array types, and function types. -- end note] Access checking is performed in a context unrelated to
To
andFrom
. Only the validity of the immediate context of the expression of the return statement (8.7.3) (including initialization of the returned object or reference) is considered. [Note: The initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the "immediate context" and can result in the program being ill-formed. -- end note]
関連URL
- cppreference: is_convertible, convertible_to
- cpprefjp: is_convertible, convertible_to