Metafunction returning the common data type between two data types.
common
is a natural extension of the std::common_type
metafunction to data types. Given two data types T
and U
, we say that they share a common type C
if both objects of data type T
and objects of data type U
may be converted (using to
) to an object of data type C
, and if that conversion is equality preserving. In other words, this means that for any objects t1, t2
of data type T
and u1, u2
of data type U
, the following law is satisfied:
The role of common
is to provide an alias to such a C
if it exists. In other words, if T
and U
have a common data type C
, common<T, U>::type
is an alias to C
. Otherwise, common<T, U>
has no nested type
and can be used in dependent contexts to exploit SFINAE. By default, the exact steps followed by common
to determine the common type C
of T
and U
are
T
and U
are the same, then C
is T
.true ? std::declval<T>() : std::declval<U>()
is well-formed, then C
is the type of this expression after using std::decay
on it. This is exactly the type that would have been returned by std::common_type
, except that custom specializations of std::common_type
are not taken into account.common<T, U>
does not have a nested type
alias, unless it is specialized explicitly.As point 3 suggests, it is also possible (and sometimes necessary) to specialize common
in the boost::hana
namespace for pairs of custom data types when the default behavior of common
is not sufficient. Note that when
-based specialization is supported when specializing common
in the boost::hana
namespace.
#### Rationale for requiring the conversion to be equality-preserving This decision is aligned with a proposed concept design for the standard library (N3351). Also, if we did not require this, then all data types would trivially share the common data type
void
, since all objects can be converted to it.