20 General utilities library [utilities]

20.10 Metaprogramming and type traits [meta]

20.10.4 Unary type traits [meta.unary]

20.10.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]) remove_all_extents_t<T> shall be a complete type or (possibly cv-qualified) void.
template <class T>
struct is_trivially_copyable;
T is a trivially copyable type ([basic.types]) remove_all_extents_t<T> shall be a complete type or (possibly cv-qualified) void.
template <class T>
struct is_standard_layout;
T is a standard-layout type ([basic.types]) remove_all_extents_t<T> shall be a complete type or (possibly cv-qualified) void.
template <class T>
struct is_pod;
T is a POD type ([basic.types]) remove_all_extents_t<T> shall be a complete type or (possibly cv-qualified) void.
template <class T>
struct is_literal_type;
T is a literal type ([basic.types]) remove_all_extents_t<T> shall be a complete type or (possibly cv-qualified) void.
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. If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_polymorphic;
T is a polymorphic class ([class.virtual]) If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_abstract;
T is an abstract class ([class.abstract]) If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_final;
T is a class type marked with the class-virt-specifier final (Clause [class]). [ Note: A union is a class type that can be marked with final.  — end note ] If T is a class type, T shall be a complete type.
template <class T>
struct is_signed;
If is_arithmetic<T>::value is true, the same result as integral_constant<bool, T(-1) < T(0)>::value; otherwise, false
template <class T>
struct is_unsigned;
If is_arithmetic<T>::value is true, the same result as integral_constant<bool, T(0) < T(-1)>::value; otherwise, false
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;
For a referenceable type T, the same result as is_constructible<T, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_move_constructible;
For a referenceable type T, the same result as is_constructible<T, T&&>::value, otherwise false. 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;
For a referenceable type T, the same result as is_assignable<T&, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_move_assignable;
For a referenceable type T, the same result as is_assignable<T&, T&&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_destructible;
For reference types, is_destructible<T>::value is true.
For incomplete types and function types, is_destructible<T>::value is false.
For object types and given U equal to remove_all_extents_t<T>, if the expression std::declval<U&>().~U() is well-formed when treated as an unevaluated operand (Clause [expr]),
then is_destructible<T>::value is true, otherwise it is false.
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;
For a referenceable type T, the same result as is_trivially_constructible<T, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_move_constructible;
For a referenceable type T, the same result as is_trivially_constructible<T, T&&>::value, otherwise false. 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;
For a referenceable type T, the same result as is_trivially_assignable<T&, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_trivially_move_assignable;
For a referenceable type T, the same result as is_trivially_assignable<T&, T&&>::value, otherwise false. 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;
For a referenceable type T, the same result as is_nothrow_constructible<T, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_move_constructible;
For a referenceable type T, the same result as is_nothrow_constructible<T, T&&>::value, otherwise false. 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;
For a referenceable type T, the same result as is_nothrow_assignable<T&, const T&>::value, otherwise false. T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound.
template <class T>
struct is_nothrow_move_assignable;
For a referenceable type T, the same result as is_nothrow_assignable<T&, T&&>::value, otherwise false. 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]) If T is a non-union class type, T shall be a complete type.

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_t<const volatile int>  // volatile int
remove_const_t<const int* const>    // const int*
remove_const_t<const int&>          // const int&
remove_const_t<const int[3]>        // int[3]

 — end example ]

Example:

// Given:
struct P final { };
union U1 { };
union U2 final { };

// the following assertions hold:
static_assert(!is_final<int>::value, "Error!");
static_assert( is_final<P>::value, "Error!");
static_assert(!is_final<U1>::value, "Error!");
static_assert( is_final<U2>::value, "Error!");

 — end example ]

Given the following function prototype:

template <class T>
  add_rvalue_reference_t<T> create() noexcept;

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 ]