Template | Condition | Comments |
template <std::size_t Len, std::size_t Align = default-alignment> struct aligned_storage; | Len shall not be zero. Align shall be equal to alignof(T) for some type T or to default-alignment. | 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 POD type suitable for use as uninitialized storage for any object whose size is at most Len and whose alignment is a divisor of Align. |
template <std::size_t Len, class... Types> struct aligned_union; | At least one type is provided. | The member typedef type shall be a POD 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 std::size_t whose value is the strictest alignment of all types listed in Types. |
template <class T> struct decay; | Let U be remove_reference<T>::type. If is_array<U>::value is true, the member typedef type shall equal remove_extent<U>::type*. If is_function<U>::value is true, the member typedef type shall equal add_pointer<U>::type. Otherwise the member typedef type equals remove_cv<U>::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 expression 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 = void> struct enable_if; | If B is true, the member typedef type shall equal T; otherwise, there shall be no member typedef type. | |
template <bool B, class T, class F> struct conditional; | If B is true, the member typedef type shall equal T. If B is false, the member typedef type shall equal F. | |
template <class... T> struct common_type; | The member typedef type shall be defined as set out below. All types in the parameter pack T shall be complete or (possibly cv) void. A program may specialize this trait if at least one template parameter in the specialization is a user-defined type. [ Note: Such specializations are needed when only explicit conversions are desired among the template arguments. — end note ] | |
template <class T> struct underlying_type; | T shall be an enumeration type ([dcl.enum]) | The member typedef type shall name the underlying type of T. |
template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>; | Fn shall be a callable type ([func.def]), reference to function, or reference to callable type. The expression decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...)) shall be well formed. | The member typedef type shall name the type decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...)) |
[ Note: A typical implementation would define aligned_storage as:
template <std::size_t Len, std::size_t Alignment> struct aligned_storage { typedef struct { alignas(Alignment) unsigned char __data[Len]; } type; };
— end note ]
It is implementation-defined whether any extended alignment is supported ([basic.align]).
The nested typedef common_type::type shall be defined as follows:
template <class ...T> struct common_type; template <class T> struct common_type<T> { typedef T type; }; template <class T, class U> struct common_type<T, U> { typedef decltype(true ? declval<T>() : declval<U>()) type; }; template <class T, class U, class... V> struct common_type<T, U, V...> { typedef typename common_type<typename common_type<T, U>::type, V...>::type type; };
[ Example: Given these definitions:
typedef bool (&PF1)(); typedef short (*PF2)(long); struct S { operator PF2() const; double operator()(char, int&); void fn(long) const; char data; }; typedef void (S::*PMF)(long) const; typedef char S::*PMD;
the following assertions will hold:
static_assert(is_same<result_of<S(int)>::type, short>::value, "Error!"); static_assert(is_same<result_of<S&(unsigned char, int&)>::type, double>::value, "Error!"); static_assert(is_same<result_of<PF1()>::type, bool>::value, "Error!"); static_assert(is_same<result_of<PMF(unique_ptr<S>, int)>::type, void>::value, "Error!"); static_assert(is_same<result_of<PMD(S)>::type, char&&>::value, "Error!"); static_assert(is_same<result_of<PMD(const S*)>::type, const char&>::value, "Error!");
— end example ]