23 General utilities library [utilities]

23.15 Metaprogramming and type traits [meta]

23.15.6 Relationships between types [meta.rel]

This subclause contains templates that may be used to query relationships between types at compile time.

Each of these templates shall be a BinaryTypeTrait with a base characteristic of true_­type if the corresponding condition is true, otherwise false_­type.

Table 44 — Type relationship predicates
TemplateConditionComments
template <class T, class U>
struct is_­same;
T and U name the same type with the same cv-qualifications
template <class Base, class Derived>
struct is_­base_­of;
Base is a base class of Derived (Clause [class.derived]) without regard to cv-qualifiers or Base and Derived are not unions and name the same class type without regard to cv-qualifiers If Base and Derived are non-union class types and are not possibly cv-qualified versions of the same type, Derived shall be a complete type. [Note: Base classes that are private, protected, or ambiguous are, nonetheless, base classes. end note]
template <class From, class To>
struct is_­convertible;
see below From and To shall be complete types, arrays of unknown bound, or cv void types.
template <class Fn, class... ArgTypes>
struct is_­invocable;
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­invocable_­r;
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class Fn, class... ArgTypes>
struct is_­nothrow_­invocable;
is_­invocable_­v<
Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­nothrow_­invocable_­r;
is_­invocable_­r_­v<
R, Fn, ArgTypes...> is true and the expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.

For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any type T is considered to be a trivial ([basic.types], [special]) function call that is not an odr-use of declval in the context of the corresponding definition notwithstanding the restrictions of [declval].

[Example:

struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : private B1, private B2 {};

is_base_of_v<B, D>         // true
is_base_of_v<const B, D>   // true
is_base_of_v<B, const D>   // true
is_base_of_v<B, const B>   // true
is_base_of_v<D, B>         // false
is_base_of_v<B&, D&>       // false
is_base_of_v<B[3], D[3]>   // false
is_base_of_v<int, int>     // false

end example]

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 (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]