namespace std { // [meta.help], helper class template<class T, T v> struct integral_constant; template<bool B> using bool_constant = integral_constant<bool, B>; using true_type = bool_constant<true>; using false_type = bool_constant<false>; // [meta.unary.cat], primary type categories template<class T> struct is_void; template<class T> struct is_null_pointer; template<class T> struct is_integral; template<class T> struct is_floating_point; template<class T> struct is_array; template<class T> struct is_pointer; template<class T> struct is_lvalue_reference; template<class T> struct is_rvalue_reference; template<class T> struct is_member_object_pointer; template<class T> struct is_member_function_pointer; template<class T> struct is_enum; template<class T> struct is_union; template<class T> struct is_class; template<class T> struct is_function; // [meta.unary.comp], composite type categories template<class T> struct is_reference; template<class T> struct is_arithmetic; template<class T> struct is_fundamental; template<class T> struct is_object; template<class T> struct is_scalar; template<class T> struct is_compound; template<class T> struct is_member_pointer; // [meta.unary.prop], type properties template<class T> struct is_const; template<class T> struct is_volatile; template<class T> struct is_trivial; template<class T> struct is_trivially_copyable; template<class T> struct is_standard_layout; template<class T> struct is_empty; template<class T> struct is_polymorphic; template<class T> struct is_abstract; template<class T> struct is_final; template<class T> struct is_aggregate; template<class T> struct is_signed; template<class T> struct is_unsigned; template<class T> struct is_bounded_array; template<class T> struct is_unbounded_array; template<class T, class... Args> struct is_constructible; template<class T> struct is_default_constructible; template<class T> struct is_copy_constructible; template<class T> struct is_move_constructible; template<class T, class U> struct is_assignable; template<class T> struct is_copy_assignable; template<class T> struct is_move_assignable; template<class T, class U> struct is_swappable_with; template<class T> struct is_swappable; template<class T> struct is_destructible; template<class T, class... Args> struct is_trivially_constructible; template<class T> struct is_trivially_default_constructible; template<class T> struct is_trivially_copy_constructible; template<class T> struct is_trivially_move_constructible; template<class T, class U> struct is_trivially_assignable; template<class T> struct is_trivially_copy_assignable; template<class T> struct is_trivially_move_assignable; template<class T> struct is_trivially_destructible; template<class T, class... Args> struct is_nothrow_constructible; template<class T> struct is_nothrow_default_constructible; template<class T> struct is_nothrow_copy_constructible; template<class T> struct is_nothrow_move_constructible; template<class T, class U> struct is_nothrow_assignable; template<class T> struct is_nothrow_copy_assignable; template<class T> struct is_nothrow_move_assignable; template<class T, class U> struct is_nothrow_swappable_with; template<class T> struct is_nothrow_swappable; template<class T> struct is_nothrow_destructible; template<class T> struct has_virtual_destructor; template<class T> struct has_unique_object_representations; // [meta.unary.prop.query], type property queries template<class T> struct alignment_of; template<class T> struct rank; template<class T, unsigned I = 0> struct extent; // [meta.rel], type relations template<class T, class U> struct is_same; template<class Base, class Derived> struct is_base_of; template<class From, class To> struct is_convertible; template<class From, class To> struct is_nothrow_convertible; template<class T, class U> struct is_layout_compatible; template<class Base, class Derived> struct is_pointer_interconvertible_base_of; template<class Fn, class... ArgTypes> struct is_invocable; template<class R, class Fn, class... ArgTypes> struct is_invocable_r; template<class Fn, class... ArgTypes> struct is_nothrow_invocable; template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r; // [meta.trans.cv], const-volatile modifications template<class T> struct remove_const; template<class T> struct remove_volatile; template<class T> struct remove_cv; template<class T> struct add_const; template<class T> struct add_volatile; template<class T> struct add_cv; template<class T> using remove_const_t = typename remove_const<T>::type; template<class T> using remove_volatile_t = typename remove_volatile<T>::type; template<class T> using remove_cv_t = typename remove_cv<T>::type; template<class T> using add_const_t = typename add_const<T>::type; template<class T> using add_volatile_t = typename add_volatile<T>::type; template<class T> using add_cv_t = typename add_cv<T>::type; // [meta.trans.ref], reference modifications template<class T> struct remove_reference; template<class T> struct add_lvalue_reference; template<class T> struct add_rvalue_reference; template<class T> using remove_reference_t = typename remove_reference<T>::type; template<class T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; template<class T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; // [meta.trans.sign], sign modifications template<class T> struct make_signed; template<class T> struct make_unsigned; template<class T> using make_signed_t = typename make_signed<T>::type; template<class T> using make_unsigned_t = typename make_unsigned<T>::type; // [meta.trans.arr], array modifications template<class T> struct remove_extent; template<class T> struct remove_all_extents; template<class T> using remove_extent_t = typename remove_extent<T>::type; template<class T> using remove_all_extents_t = typename remove_all_extents<T>::type; // [meta.trans.ptr], pointer modifications template<class T> struct remove_pointer; template<class T> struct add_pointer; template<class T> using remove_pointer_t = typename remove_pointer<T>::type; template<class T> using add_pointer_t = typename add_pointer<T>::type; // [meta.trans.other], other transformations template<class T> struct type_identity; template<size_t Len, size_t Align = default-alignment> // see [meta.trans.other] struct aligned_storage; template<size_t Len, class... Types> struct aligned_union; template<class T> struct remove_cvref; template<class T> struct decay; template<bool, class T = void> struct enable_if; template<bool, class T, class F> struct conditional; template<class... T> struct common_type; template<class T, class U, template<class> class TQual, template<class> class UQual> struct basic_common_reference { }; template<class... T> struct common_reference; template<class T> struct underlying_type; template<class Fn, class... ArgTypes> struct invoke_result; template<class T> struct unwrap_reference; template<class T> struct unwrap_ref_decay; template<class T> using type_identity_t = typename type_identity<T>::type; template<size_t Len, size_t Align = default-alignment> // see [meta.trans.other] using aligned_storage_t = typename aligned_storage<Len, Align>::type; template<size_t Len, class... Types> using aligned_union_t = typename aligned_union<Len, Types...>::type; template<class T> using remove_cvref_t = typename remove_cvref<T>::type; template<class T> using decay_t = typename decay<T>::type; template<bool b, class T = void> using enable_if_t = typename enable_if<b, T>::type; template<bool b, class T, class F> using conditional_t = typename conditional<b, T, F>::type; template<class... T> using common_type_t = typename common_type<T...>::type; template<class... T> using common_reference_t = typename common_reference<T...>::type; template<class T> using underlying_type_t = typename underlying_type<T>::type; template<class Fn, class... ArgTypes> using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type; template<class T> using unwrap_reference_t = typename unwrap_reference<T>::type; template<class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; template<class...> using void_t = void; // [meta.logical], logical operator traits template<class... B> struct conjunction; template<class... B> struct disjunction; template<class B> struct negation; // [meta.unary.cat], primary type categories template<class T> inline constexpr bool is_void_v = is_void<T>::value; template<class T> inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value; template<class T> inline constexpr bool is_integral_v = is_integral<T>::value; template<class T> inline constexpr bool is_floating_point_v = is_floating_point<T>::value; template<class T> inline constexpr bool is_array_v = is_array<T>::value; template<class T> inline constexpr bool is_pointer_v = is_pointer<T>::value; template<class T> inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value; template<class T> inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value; template<class T> inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<T>::value; template<class T> inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<T>::value; template<class T> inline constexpr bool is_enum_v = is_enum<T>::value; template<class T> inline constexpr bool is_union_v = is_union<T>::value; template<class T> inline constexpr bool is_class_v = is_class<T>::value; template<class T> inline constexpr bool is_function_v = is_function<T>::value; // [meta.unary.comp], composite type categories template<class T> inline constexpr bool is_reference_v = is_reference<T>::value; template<class T> inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value; template<class T> inline constexpr bool is_fundamental_v = is_fundamental<T>::value; template<class T> inline constexpr bool is_object_v = is_object<T>::value; template<class T> inline constexpr bool is_scalar_v = is_scalar<T>::value; template<class T> inline constexpr bool is_compound_v = is_compound<T>::value; template<class T> inline constexpr bool is_member_pointer_v = is_member_pointer<T>::value; // [meta.unary.prop], type properties template<class T> inline constexpr bool is_const_v = is_const<T>::value; template<class T> inline constexpr bool is_volatile_v = is_volatile<T>::value; template<class T> inline constexpr bool is_trivial_v = is_trivial<T>::value; template<class T> inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value; template<class T> inline constexpr bool is_standard_layout_v = is_standard_layout<T>::value; template<class T> inline constexpr bool is_empty_v = is_empty<T>::value; template<class T> inline constexpr bool is_polymorphic_v = is_polymorphic<T>::value; template<class T> inline constexpr bool is_abstract_v = is_abstract<T>::value; template<class T> inline constexpr bool is_final_v = is_final<T>::value; template<class T> inline constexpr bool is_aggregate_v = is_aggregate<T>::value; template<class T> inline constexpr bool is_signed_v = is_signed<T>::value; template<class T> inline constexpr bool is_unsigned_v = is_unsigned<T>::value; template<class T> inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value; template<class T> inline constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value; template<class T, class... Args> inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value; template<class T> inline constexpr bool is_default_constructible_v = is_default_constructible<T>::value; template<class T> inline constexpr bool is_copy_constructible_v = is_copy_constructible<T>::value; template<class T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_assignable_v = is_assignable<T, U>::value; template<class T> inline constexpr bool is_copy_assignable_v = is_copy_assignable<T>::value; template<class T> inline constexpr bool is_move_assignable_v = is_move_assignable<T>::value; template<class T, class U> inline constexpr bool is_swappable_with_v = is_swappable_with<T, U>::value; template<class T> inline constexpr bool is_swappable_v = is_swappable<T>::value; template<class T> inline constexpr bool is_destructible_v = is_destructible<T>::value; template<class T, class... Args> inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value; template<class T> inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<T>::value; template<class T> inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value; template<class T> inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value; template<class T> inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<T>::value; template<class T> inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<T>::value; template<class T> inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value; template<class T, class... Args> inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value; template<class T> inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<T>::value; template<class T> inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value; template<class T> inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value; template<class T> inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value; template<class T> inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<T>::value; template<class T, class U> inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value; template<class T> inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value; template<class T> inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value; template<class T> inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value; template<class T> inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<T>::value; // [meta.unary.prop.query], type property queries template<class T> inline constexpr size_t alignment_of_v = alignment_of<T>::value; template<class T> inline constexpr size_t rank_v = rank<T>::value; template<class T, unsigned I = 0> inline constexpr size_t extent_v = extent<T, I>::value; // [meta.rel], type relations template<class T, class U> inline constexpr bool is_same_v = is_same<T, U>::value; template<class Base, class Derived> inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value; template<class From, class To> inline constexpr bool is_convertible_v = is_convertible<From, To>::value; template<class From, class To> inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value; template<class T, class U> inline constexpr bool is_layout_compatible_v = is_layout_compatible<T, U>::value; template<class Base, class Derived> inline constexpr bool is_pointer_interconvertible_base_of_v = is_pointer_interconvertible_base_of<Base, Derived>::value; template<class Fn, class... ArgTypes> inline constexpr bool is_invocable_v = is_invocable<Fn, ArgTypes...>::value; template<class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value; template<class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value; template<class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value; // [meta.logical], logical operator traits template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value; template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value; template<class B> inline constexpr bool negation_v = negation<B>::value; // [meta.member], member relationships template<class S, class M> constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept; template<class S1, class S2, class M1, class M2> constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept; // [meta.const.eval], constant evaluation context constexpr bool is_constant_evaluated() noexcept; }
namespace std { template<class T, T v> struct integral_constant { static constexpr T value = v; using value_type = T; using type = integral_constant<T, v>; constexpr operator value_type() const noexcept { return value; } constexpr value_type operator()() const noexcept { return value; } }; }
Template | Condition | Comments |
T is void | ||
T is an integral type ([basic.fundamental]) | ||
T is a floating-point type ([basic.fundamental]) | ||
T is an array type ([basic.compound]) of known or unknown extent | ||
T is a pointer type ([basic.compound]) | Includes pointers to functions
but not pointers to non-static members. | |
T is an lvalue reference type ([dcl.ref]) | ||
T is an rvalue reference type ([dcl.ref]) | ||
T is a pointer to data member | ||
T is a pointer to member function | ||
T is an enumeration type ([basic.compound]) | ||
T is a union type ([basic.compound]) | ||
T is a non-union class type ([basic.compound]) | ||
T is a function type ([basic.compound]) |
Template | Condition | Comments |
T is an lvalue reference or an rvalue reference | ||
T is an arithmetic type ([basic.fundamental]) | ||
T is a fundamental type ([basic.fundamental]) | ||
T is an object type ([basic.types]) | ||
T is a scalar type ([basic.types]) | ||
T is a compound type ([basic.compound]) | ||
T is a pointer-to-member type |
Template | Condition | Preconditions |
T is const-qualified ([basic.type.qualifier]) | ||
T is volatile-qualified ([basic.type.qualifier]) | ||
T is a trivial type ([basic.types]) | ||
T is a trivially copyable type ([basic.types]) | ||
T is a standard-layout type ([basic.types]) | ||
T is a class type, but not a union type, with no non-static data
members other than subobjects of zero size, no virtual member functions,
no virtual base classes, and no base class B for
which is_empty_v<B> is false. | ||
T is a polymorphic class ([class.virtual]) | ||
T is an abstract class ([class.abstract]) | ||
T is an aggregate type ([dcl.init.aggr]) | ||
If is_arithmetic_v<T> is true, the same result as
T(-1) < T(0);
otherwise, false | ||
If is_arithmetic_v<T> is true, the same result as
T(0) < T(-1);
otherwise, false | ||
T is an array type of known bound ([dcl.array]) | ||
T is an array type of unknown bound ([dcl.array]) | ||
For a function type T or
for a cv void type T,
is_constructible_v<T, Args...> is false,
otherwise see below | T and all types in the template parameter pack Args
shall be complete types, cv void,
or arrays of unknown bound. | |
For a referenceable type T ([defns.referenceable]), the same result as
is_constructible_v<T, const T&>, otherwise false. | ||
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 | ||
The expressions swap(declval<T>(), declval<U>()) and
swap(declval<U>(), declval<T>()) are each well-formed
when treated as an unevaluated operand
in an overload-resolution context
for swappable values ([swappable.requirements]). Only the validity of the immediate context
of the swap expressions is considered. [ Note : ]The compilation of the expressions 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 | ||
Either T is a reference type,
or T is a complete object type
for which the expression
declval<U&>().~U()
is well-formed
when treated as an unevaluated operand,
where U is
remove_all_extents_t<T>. | ||
is_constructible_v<T, Args...> 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 template parameter pack Args shall be complete types,
cv void, or arrays of unknown bound. | |
For a referenceable type T, the same result as
is_trivially_constructible_v<T, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_trivially_constructible_v<T, T&&>, otherwise false. | ||
is_assignable_v<T, U> is true and the assignment, as defined by
is_assignable, is known to call no operation that is not trivial
([basic.types], [special]). | ||
For a referenceable type T, the same result as
is_trivially_assignable_v<T&, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_trivially_assignable_v<T&, T&&>, otherwise false. | ||
is_destructible_v<T> is true and
remove_all_extents_t<T> is either a non-class type or
a class type with a trivial destructor. | ||
is_constructible_v<T, Args...> 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 template parameter pack Args
shall be complete types, cv void,
or arrays of unknown bound. | |
For a referenceable type T, the same result as
is_nothrow_constructible_v<T, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_nothrow_constructible_v<T, T&&>, otherwise false. | ||
is_assignable_v<T, U> is true and the assignment is known not to
throw any exceptions ([expr.unary.noexcept]). | ||
For a referenceable type T, the same result as
is_nothrow_assignable_v<T&, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_nothrow_assignable_v<T&, T&&>, otherwise false. | ||
is_swappable_with_v<T, U> is true and
each swap expression of the definition of
is_swappable_with<T, U> is known not to throw
any exceptions ([expr.unary.noexcept]). | ||
For a referenceable type T,
the same result as is_nothrow_swappable_with_v<T&, T&>,
otherwise false. | ||
is_destructible_v<T> is true and the indicated destructor is known
not to throw any exceptions ([expr.unary.noexcept]). | ||
T has a virtual destructor ([class.dtor]) | ||
For an array type T, the same result as
has_unique_object_representations_v<remove_all_extents_t<T>>,
otherwise see below. |
is_const_v<const volatile int> // true is_const_v<const int*> // false is_const_v<const int&> // false is_const_v<int[3]> // false is_const_v<const int[3]> // trueβ end 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
// Given: struct P final { }; union U1 { }; union U2 final { }; // the following assertions hold: static_assert(!is_final_v<int>); static_assert(is_final_v<P>); static_assert(!is_final_v<U1>); static_assert(is_final_v<U2>);β end example
T t(declval<Args>()...);
Template | Value |
alignof(T). | |
If T names an array type, an integer value representing
the number of dimensions of T; otherwise, 0. | |
If T is not an array type, or if it has rank less
than or equal to I, or if I is 0 and T
has type βarray of unknown bound of Uβ, then
0; otherwise, the bound ([dcl.array]) of the dimension of
T, where indexing of I is zero-based |
// the following assertions hold: assert(rank_v<int> == 0); assert(rank_v<int[2]> == 1); assert(rank_v<int[][4]> == 2);β end example
// the following assertions hold: assert(extent_v<int> == 0); assert(extent_v<int[2]> == 2); assert(extent_v<int[2][4]> == 2); assert(extent_v<int[][4]> == 0); assert((extent_v<int, 1>) == 0); assert((extent_v<int[2], 1>) == 0); assert((extent_v<int[2][4], 1>) == 4); assert((extent_v<int[][4], 1>) == 4);β end example
Template | Condition | Comments |
template<class T, class U> struct is_same; | T and U name the same type with the same cv-qualifications | |
Base is a base class of Derived ([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. | |
see below | ||
is_convertible_v<From, To> is true and
the conversion, as defined by is_convertible,
is known not to throw any exceptions ([expr.unary.noexcept]) | ||
Derived is unambiguously derived from Base
without regard to cv-qualifiers,
and each object of type Derived
is pointer-interconvertible ([basic.compound]) with
its Base subobject,
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. | |
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand | Fn and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand | Fn, R, and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
is_invocable_v< Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([expr.unary.noexcept]) | Fn and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
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 ([expr.unary.noexcept]) | Fn, R, and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. |
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
To test() { return declval<From>(); }
Template | Comments |
The member typedef type names
the same type as T
except that any top-level const-qualifier has been removed. | |
The member typedef type names
the same type as T
except that any top-level volatile-qualifier has been removed. | |
The member typedef type shall be the same as T
except that any top-level cv-qualifier has been removed. | |
If T is a reference, function, or top-level const-qualified
type, then type names
the same type as T, otherwise
T const. | |
If T is a reference, function, or top-level volatile-qualified
type, then type names
the same type as T, otherwise
T volatile. | |
Template | Comments |
If T names a (possibly cv-qualified)
signed integer type then the member typedef
type names the type T; otherwise,
if T names a (possibly cv-qualified) unsigned integer
type then type names the corresponding
signed integer type, with the same cv-qualifiers as T;
otherwise, type names the signed integer type with smallest
rank for which
sizeof(T) == sizeof(type), with the same
cv-qualifiers as T. | |
If T names a (possibly cv-qualified)
unsigned integer type then the member typedef
type names the type T; otherwise,
if T names a (possibly cv-qualified) signed integer
type then type names the corresponding
unsigned integer type, with the same cv-qualifiers as T;
otherwise, type names the unsigned integer type with smallest
rank for which
sizeof(T) == sizeof(type), with the same
cv-qualifiers as T. |
// the following assertions hold: assert((is_same_v<remove_extent_t<int>, int>)); assert((is_same_v<remove_extent_t<int[2]>, int>)); assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>)); assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));β end example
Template | Comments |
If T has type β(possibly cv-qualified) pointer
to T1β then the member typedef type
names T1; otherwise, it names T. | |
If T names a referenceable type or a
cv void type then
the member typedef type names the same type as
remove_reference_t<T>*;
otherwise, type names T. |
Template | Comments |
The value of default-alignment shall be the most
stringent alignment requirement for any C++ object type whose size
is no greater than Len ([basic.types]). The member typedef type shall be a trivial standard-layout type
suitable for use as uninitialized storage for any object whose size
is at most Len and whose alignment is a divisor of Align. | |
The member typedef type shall be a trivial standard-layout type suitable for use as
uninitialized storage for any object whose type is listed in Types;
its size shall be at least Len. The static member alignment_value
shall be an integral constant of type size_t whose value is the
strictest alignment of all types listed in Types. Each type in the template parameter pack Types
is a complete object type. | |
[ Note : ]This behavior is similar to the lvalue-to-rvalue ([conv.lval]),
array-to-pointer ([conv.array]), and function-to-pointer ([conv.func])
conversions applied when an lvalue is used as an rvalue, but also
strips cv-qualifiers from class types in order to more closely model by-value
argument passing. β end note | |
template<bool B, class T,
class F> struct conditional; | |
template<class... T> struct common_type; | Unless this trait is specialized (as specified in Note B, below),
the member type is defined or omitted as specified in Note A, below. If it is omitted, there shall be no member type. Each type in the template parameter pack T shall be
complete, cv void, or an array of unknown bound. |
Unless this trait is specialized (as specified in Note D, below),
there shall be no member type. | |
If T is an enumeration type, the member typedef type names
the underlying type of T ([dcl.enum]);
otherwise, there is no member type. | |
template<class Fn, class... ArgTypes> struct invoke_result; | If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand,
the member typedef type names the type
decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));
otherwise, there shall be no member type. Only the validity of the immediate context of the
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 notePreconditions: Fn and all types in the template parameter pack ArgTypes are complete types, cv void, or arrays of unknown bound. |
If T is
a specialization reference_wrapper<X> for some type X,
the member typedef type of unwrap_reference<T> is X&,
otherwise it is T. | |
The member typedef type of unwrap_ref_decay<T>
denotes the type unwrap_reference_t<decay_t<T>>. |
template<size_t Len, size_t Alignment> struct aligned_storage { typedef struct { alignas(Alignment) unsigned char __data[Len]; } type; };
decay_t<decltype(false ? declval<D1>() : declval<D2>())>denotes a valid type, let C denote that type.
using PF1 = bool (&)(); using PF2 = short (*)(long); struct S { operator PF2() const; double operator()(char, int&); void fn(long) const; char data; }; using PMF = void (S::*)(long) const; using PMD = char S::*;the following assertions will hold:
static_assert(is_same_v<invoke_result_t<S, int>, short>); static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>); static_assert(is_same_v<invoke_result_t<PF1>, bool>); static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>); static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>); static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
template<class... B> struct conjunction : see below { };
template<class... B> struct disjunction : see below { };
template<class B> struct negation : see below { };
template<class S, class M>
constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept;
template<class S1, class S2, class M1, class M2>
constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
struct A { int a; }; // a standard-layout class struct B { int b; }; // a standard-layout class struct C: public A, public B { }; // not a standard-layout class static_assert( is_pointer_interconvertible_with_class( &C::b ) ); // Succeeds because, despite its appearance, &C::b has type // βpointer to member of B of type intβ. static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) ); // Forces the use of class C, and fails. static_assert( is_corresponding_member( &C::a, &C::b ) ); // Succeeds because, despite its appearance, &C::a and &C::b have types // βpointer to member of A of type intβ and // βpointer to member of B of type intβ, respectively. static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) ); // Forces the use of class C, and fails.β end example
constexpr bool is_constant_evaluated() noexcept;