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;
explicit To(From) = delete;
};
struct From {
operator To() { return {}; }
};
static_assert( std::is_convertible_v<From, To> );
static_assert( !std::convertible_to<From, To> );
To to1 = From{};
To to2{From{}};
C++20(N4861) 18.4.4/p1, 20.15.6/p5より引用(下線部は強調)。
Given types From
and To
and an expression E
such that decltype((E))
is add_rvalue_reference_t<From>
, convertible_to<From, To>
requires E
to be both implicitly and explicitly convertible to type To
. 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
and From
. 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