Table 60: Other transformations [tab:meta.trans.other]

Template | Comments | |

The value of default-alignment shall be the most
stringent alignment requirement for any 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 1: 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<class... T> struct common_type; | ||

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. | ||

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 2: 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]Preconditions: 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>>. |

[*Note 3*: *end note*]

A typical implementation would define aligned_storage as:
template<size_t Len, size_t Alignment>
struct aligned_storage {
typedef struct {
alignas(Alignment) unsigned char __data[Len];
} type;
};

β In addition to being available via inclusion
of the <type_traits> header, the templates
unwrap_reference,
unwrap_ref_decay,
unwrap_reference_t, and
unwrap_ref_decay_t
are available
when the header <functional> ([functional.syn]) is included.

Let:

*CREF*(A) be add_lvalue_reference_t<const remove_reference_t<A>>,*XREF*(A) denote a unary alias template T such that T<U> denotes the same type as U with the addition of A's cv and reference qualifiers, for a non-reference cv-unqualified type U,*COPYCV*(FROM, TO) be an alias for type TO with the addition of FROM's top-level cv-qualifiers,*COND-RES*(X, Y) be decltype(false ? declval<X(&)()>()() : declval<Y(&)()>()()).

Given types A and B,
let X be remove_reference_t<A>,
let Y be remove_reference_t<B>, and
let *COMMON-REF*(A, B) be:

- If A and B are both lvalue reference types,
*COMMON-REF*(A, B) is*COND-RES*(*COPYCV*(X, Y) &,*COPYCV*(Y, X) &) if that type exists and is a reference type. - Otherwise, if A is an lvalue reference and B is an rvalue reference, then
*COMMON-REF*(A, B) is*COMMON-REF*(B, A). - Otherwise,
*COMMON-REF*(A, B) is ill-formed.

If any of the types computed above is ill-formed, then
*COMMON-REF*(A, B) is ill-formed.

Note A:
For the common_type trait applied to a template parameter pack T of types,
the member type shall be either defined or not present as follows:

- The member
*typedef-name*type shall denote the same type, if any, as common_type_t<T0, T0>; otherwise there shall be no member type. - If sizeof...(T) is two, let the first and second types constituting T be denoted by T1 and T2, respectively, and let D1 and D2 denote the same types as decay_t<T1> and decay_t<T2>, respectively.
- If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false, let C denote the same type, if any, as common_type_t<D1, D2>.
- Otherwise, if decay_t<decltype(false ? declval<D1>() : declval<D2>())> denotes a valid type, let C denote that type.
- Otherwise, if
*COND-RES*(*CREF*(D1),*CREF*(D2)) denotes a type, let C denote the type decay_t<*COND-RES*(*CREF*(D1),*CREF*(D2))>.

Otherwise, there shall be no member type. - If sizeof...(T) is greater than two, let T1, T2, and R, respectively, denote the first, second, and (pack of) remaining types constituting T.If there is such a type C, the member
*typedef-name*type shall denote the same type, if any, as common_type_t<C, R...>.Otherwise, there shall be no member type.

Note B: Notwithstanding the provisions of [meta.type.synop], and
pursuant to [namespace.std],
a program may specialize common_type<T1, T2>
for types T1 and T2 such that
is_same_v<T1, decay_t<T1>> and
is_same_v<T2, decay_t<T2>> are each true.

Such a specialization need not have a member named type,
but if it does,
the *qualified-id* common_type<T1, T2>::type shall denote
a cv-unqualified non-reference type
to which each of the types T1 and T2 is explicitly convertible.

Moreover, common_type_t<T1, T2> shall denote
the same type, if any, as does common_type_t<T2, T1>.

No diagnostic is required for a violation of this Note's rules.

Note C: For the common_reference trait applied to a parameter pack
T of types, the member type shall be either defined or not
present as follows:

- Then
- If T1 and T2 are reference types and
*COMMON-REF*(T1, T2) is well-formed, then the member typedef type denotes that type. - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
*XREF*(T1),*XREF*(T2)>::type is well-formed, then the member typedef type denotes that type. - Otherwise, if common_type_t<T1, T2> is well-formed, then the member typedef type denotes that type.
- Otherwise, there shall be no member type.

- Otherwise, if sizeof...(T) is greater than two, let T1, T2, and Rest, respectively, denote the first, second, and (pack of) remaining types comprising T.

Note D: Notwithstanding the provisions of [meta.type.synop], and
pursuant to [namespace.std], a program may partially specialize
basic_common_reference<T, U, TQual, UQual>
for types T and U such that
is_same_v<T, decay_t<T>> and
is_same_v<U, decay_t<U>> are each true.

Such a specialization need not have a member named type, but if it does,
the *qualified-id*
basic_common_reference<T, U, TQual, UQual>::type
shall denote a type
to which each of the types TQual<T> and
UQual<U> is convertible.

Moreover, basic_common_reference<T, U, TQual, UQual>::type shall denote
the same type, if any, as does
basic_common_reference<U, T, UQual, TQual>::type.

No diagnostic is required for a violation of these rules.

[*Example 2*: *end example*]

Given these definitions:
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&>);

β