20 General utilities library [utilities]

20.9 Metaprogramming and type traits [meta]

20.9.4 Unary type traits [meta.unary]

20.9.4.3 Type properties [meta.unary.prop]

These templates provide access to some of the more important properties of types.

It is unspecified whether the library defines any full or partial specializations of any of these templates.

For all of the class templates X declared in this Clause, instantiating that template with a template-argument that is a class template specialization may result in the implicit instantiation of the template argument if and only if the semantics of X require that the argument must be a complete type.

Table 49 — Type property predicates
TemplateConditionPreconditions
template <class T>
struct is_const;
T is const-qualified ([basic.type.qualifier])
template <class T>
struct is_volatile;
T is volatile-qualified ([basic.type.qualifier])
template <class T>
struct is_trivial;
T is a trivial type ([basic.types]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_copyable;
T is a trivially copyable type ([basic.types]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_standard_layout;
T is a standard-layout type ([basic.types]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_pod;
T is a POD type ([basic.types]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_literal_type;
T is a literal type ([basic.types]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_empty;
T is a class type, but not a union type, with no non-static data members other than bit-fields of length 0, no virtual member functions, no virtual base classes, and no base class B for which is_empty<B>::value is false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_polymorphic;
T is a polymorphic class ([class.virtual]) T shall be a complete type, type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_abstract;
T is an abstract class ([class.abstract]) T shall be a complete type, type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_signed;
is_arithmetic<T>::value && T(-1) < T(0)
template <class T>
struct is_unsigned;
is_arithmetic<T>::value && T(0) < T(-1)
template <class T, class... Args>
struct is_constructible;
see below T and all types in the parameter pack Args shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_default_constructible;
is_constructible<T>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_copy_constructible;
is_constructible<T, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_move_constructible;
is_constructible<T, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T, class U>
struct is_assignable;
The expression declval<T>() = declval<U>() is well-formed when treated as an unevaluated operand (Clause [expr]). Access checking is performed as if in a context unrelated to T and U. Only the validity of the immediate context of the assignment expression is considered. [ Note: The compilation of the expression 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 ] T and U shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_copy_assignable;
is_assignable<T&, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_move_assignable;
is_assignable<T&, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_destructible;
For a complete type T and given
template <class U> struct test { U u; };,
test<T>::~test() is not deleted.
T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T, class... Args>
struct
is_trivially_constructible;
is_constructible<T,
Args...>::value is true and the variable definition for is_constructible, as defined below, is known to call no operation that is not trivial ( [basic.types], [special]).
T and all types in the parameter pack Args shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_trivially_default_constructible;
is_trivially_constructible<T>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_copy_constructible;
is_trivially_constructible<T, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_move_constructible;
is_trivially_constructible<T, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T, class U>
struct is_trivially_assignable;
is_assignable<T, U>::value is true and the assignment, as defined by is_assignable, is known to call no operation that is not trivial ([basic.types], [special]). T and U shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_trivially_copy_assignable;
is_trivially_assignable<T&, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_move_assignable;
is_trivially_assignable<T&, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_destructible;
is_destructible<T>::value is true and the indicated destructor is known to be trivial. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T, class... Args>
struct is_nothrow_constructible;
is_constructible<T, Args...>::value is true and the variable definition for is_constructible, as defined below, is known not to throw any exceptions ([expr.unary.noexcept]). T and all types in the parameter pack Args shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_nothrow_default_constructible;
is_nothrow_constructible<T>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_copy_constructible;
is_nothrow_constructible<T, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_move_constructible;
is_nothrow_constructible<T, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T, class U>
struct is_nothrow_assignable;
is_assignable<T, U>::value is true and the assignment is known not to throw any exceptions ([expr.unary.noexcept]). T and U shall be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
template <class T>
struct is_nothrow_copy_assignable;
is_nothrow_assignable<T&, const T&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_move_assignable;
is_nothrow_assignable<T&, T&&>::value is true. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_destructible;
is_destructible<T>::value is true and the indicated destructor is known not to throw any exceptions ([expr.unary.noexcept]). T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct has_virtual_destructor;
T has a virtual destructor ([class.dtor]) T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.

Example:

is_const<const volatile int>::value     // true
is_const<const int*>::value             // false
is_const<const int&>::value             // false
is_const<int[3]>::value                 // false
is_const<const int[3]>::value           // true

 — end example ]

Example:

remove_const<const volatile int>::type  // volatile int
remove_const<const int* const>::type    // const int*
remove_const<const int&>::type          // const int&
remove_const<const int[3]>::type        // int[3]

 — end example ]

Given the following function prototype:

template <class T>
  typename add_rvalue_reference<T>::type create();

the predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:

T t(create<Args>()...);

Note: These tokens are never interpreted as a function declaration.  — end note ] Access checking is performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of 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 ]