20 General utilities library [utilities]

20.9 Metaprogramming and type traits [meta]

20.9.4 Unary type traits [meta.unary]

This sub-clause contains templates that may be used to query the properties of a type at compile time.

Each of these templates shall be a UnaryTypeTrait ([meta.rqmts]) with a BaseCharacteristic of true_type if the corresponding condition is true, otherwise false_type.

20.9.4.1 Primary type categories [meta.unary.cat]

The primary type categories correspond to the descriptions given in section [basic.types] of the C++ standard.

For any given type T, the result of applying one of these templates to T and to cv-qualified T shall yield the same result.

Note: For any given type T, exactly one of the primary type categories has a value member that evaluates to true.  — end note ]

Table 47 — Primary type category predicates
TemplateConditionComments
template <class T>
struct is_void;
T is void
template <class T>
struct is_integral;
T is an integral type ([basic.fundamental])
template <class T>
struct is_floating_point;
T is a floating point type ([basic.fundamental])
template <class T>
struct is_array;
T is an array type ([basic.compound]) of known or unknown extent Class template array ([array]) is not an array type.
template <class T>
struct is_pointer;
T is a pointer type ([basic.compound]) Includes pointers to functions but not pointers to non-static members.
template <class T>
struct is_lvalue_reference;
T is an lvalue reference type ([dcl.ref])
template <class T>
struct is_rvalue_reference;
T is an rvalue reference type ([dcl.ref])
template <class T>
struct is_member_object_pointer;
T is a pointer to non-static data member
template <class T>
struct is_member_function_pointer;
T is a pointer to non-static member function
template <class T>
struct is_enum;
T is an enumeration type ([basic.compound])
template <class T>
struct is_union;
T is a union type ([basic.compound])
template <class T>
struct is_class;
T is a class type but not a union type ([basic.compound])
template <class T>
struct is_function;
T is a function type ([basic.compound])

20.9.4.2 Composite type traits [meta.unary.comp]

These templates provide convenient compositions of the primary type categories, corresponding to the descriptions given in section [basic.types].

For any given type T, the result of applying one of these templates to T, and to cv-qualified T shall yield the same result.

Table 48 — Composite type category predicates
TemplateConditionComments
template <class T>
struct is_reference;
T is an lvalue reference or an rvalue reference
template <class T>
struct is_arithmetic;
T is an arithmetic type ([basic.fundamental])
template <class T>
struct is_fundamental;
T is a fundamental type ([basic.fundamental])
template <class T>
struct is_object;
T is an object type ([basic.types])
template <class T>
struct is_scalar;
T is a scalar type ([basic.types])
template <class T>
struct is_compound;
T is a compound type ([basic.compound])
template <class T>
struct is_member_pointer;
T is a pointer to non-static data member or non-static member function

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 ]