|  | Home | Libraries | People | FAQ | More | 
        Header:  #include
        <boost/type_traits/common_type.hpp>
        or  #include <boost/type_traits.hpp>
      
namespace boost { template <class... T> struct common_type; template<class... T> using common_type_t = typename common_type<T...>::type; // C++11 and above }
        common_type is a traits class
        used to deduce a type common to a several types, useful as the return type
        of functions operating on multiple input types such as in mixed-mode arithmetic..
      
        The nested typedef ::type
        could be defined as follows:
      
template <class... T> struct common_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; }; template <> struct common_type<> { }; template <class T> struct common_type<T> { typedef typename decay<T>::type type; }; template <class T, class U> struct common_type<T, U> { typedef typename decay< decltype( declval<bool>()? declval<typename decay<T>::type>(): declval<typename decay<U>::type>() ) >::type type; };
        All parameter types must be complete. This trait is permitted to be specialized
        by a user if at least one template parameter is a user-defined type. Note: Such specializations are required when only
        explicit conversions are desired among the common_type
        arguments.
      
        Note that when the compiler does not support variadic templates (and the
        macro BOOST_NO_CXX11_VARIADIC_TEMPLATES
        is defined) then the maximum number of template arguments is 9.
      
        In a nutshell, common_type
        is a trait that takes 1 or more types, and returns a type which all of the
        types will convert to. The default definition demands this conversion be
        implicit. However the trait can be specialized for user-defined types which
        want to limit their inter-type conversions to explicit, and yet still want
        to interoperate with the common_type
        facility.
      
Example:
template <class T, class U> complex<typename common_type<T, U>::type> operator+(complex<T>, complex<U>);
        In the above example, "mixed-mode" complex arithmetic is allowed.
        The return type is described by common_type.
        For example the resulting type of adding a complex<float> and complex<double> might be a complex<double>.
      
Here is how someone might produce a variadic comparison function:
template <class ...T> typename common_type<T...>::type min(T... t);
This is a very useful and broadly applicable utility.
Another choice for the author of the preceding operator could be
template <class T, class U> typename common_type<complex<T>, complex<U> >::type operator+(complex<T>, complex<U>);
        As the default definition of common_type
        demands the conversion be implicit, we need to specialize the trait for complex
        types as follows.
      
template <class T, class U> struct common_type<complex<T>, complex<U> > { typedef complex< common_type<T, U> > type; };
common_type<> template arguments?
      The order of the template parameters is important.
        common_type<A,B,C>::type is not equivalent to common_type<C,A,B>::type, but to common_type<common_type<A,B>::type, C>::type.
      
Consider
struct A {}; struct B {}; struct C { C() {} C(A const&) {} C(B const&) {} C& operator=(C const&) { return *this; } };
The following doesn't compile
typedef boost::common_type<A, B, C>::type ABC; // Does not compile
while
typedef boost::common_type<C, A, B>::type ABC;
compiles.
        Thus, as common_type<A,B>::type
        is undefined, common_type<A,B,C>::type
        is also undefined.
      
        It is intended that clients who wish for common_type<A,
        B>
        to be well defined to define it themselves:
      
namespace boost { template <> struct common_type<A, B> {typedef C type;}; }
        Now this client can ask for common_type<A,
        B, C> (and
        get the same answer).
      
        Clients wanting to ask common_type<A,
        B, C> in
        any order and get the same result need to add in addition:
      
namespace boost { template <> struct common_type<B, A> : public common_type<A, B> {}; }
        This is needed as the specialization of common_type<A,
        B>
        is not be used implicitly for common_type<B,
        A>.
      
common_type of two types
        be a third type?
      
        Given the preceding example, one might expect common_type<A,B>::type to be C
        without any intervention from the user. But the default common_type<> implementation doesn't grant that.
        It is intended that clients who wish for common_type<A,
        B>
        to be well defined to define it themselves:
      
namespace boost { template <> struct common_type<A, B> {typedef C type;}; template <> struct common_type<B, A> : public common_type<A, B> {}; }
        Now this client can ask for common_type<A,
        B>.
      
common_type behave with
        pointers?
      Consider
struct C { }: struct B : C { }; struct A : C { };
        Shouldn't common_type<A*,B*>::type
        be C*?
        I would say yes, but the default implementation will make it ill-formed.
      
The library could add a specialization for pointers, as
namespace boost { template <typename A, typename B> struct common_type<A*, B*> { typedef common_type<A, B>* type; }; }
But in the absence of a motivating use cases, we prefer not to add more than the standard specifies.
Of course the user can always make this specialization.
common_type
        against Boost.Typeof?
      
        Even if they appear to be close, common_type
        and typeof have different
        purposes. You use typeof
        to get the type of an expression, while you use common_type
        to set explicitly the type returned of a template function. Both are complementary,
        and indeed common_type is
        approximately equivalent to decltype(declval<bool>()
        ? declval<T>()
        : declval<U>()).
      
        common_type is also similar
        to promote_args<class ...T> in
        boost/math/tools/promotion.hpp, though
        it is not exactly the same as promote_args
        either. common_type<T1, T2>::type
        simply represents the result of some operation on T1
        and T2, and defaults to the
        type obtained by putting T1
        and T2 into a conditional
        statement.
      
It is meant to be customizable (via specialization) if this default is not appropriate.