boost::hana::common< T, U, enabler > Struct Template Reference
Core

## Description

### template<typename T, typename U, optional when-based enabler>
struct boost::hana::common< T, U, enabler >

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:

to<C>(t1) == to<C>(t2) if and only if t1 == t2
to<C>(u1) == to<C>(u2) if and only if u1 == u2

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

1. If `T` and `U` are the same, then `C` is `T`.
2. Otherwise, if `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.
3. Otherwise, no common data type is detected and `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.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/core/common.hpp>
#include <type_traits>
namespace hana = boost::hana;
struct Person { };
struct Employee : Person { };
static_assert(std::is_same<hana::common<int, float>::type, float>{}, "");
static_assert(std::is_same<hana::common<Person, Employee>::type, Person>{}, "");
int main() { }
common.hpp
Defines boost::hana::common and boost::hana::common_t.
boost::hana
Namespace containing everything in the library.
Definition: accessors.hpp:20