std::common_type

From cppreference.com
 
 
 
Type support
Basic types
Fundamental types
Fixed width integer types (C++11)
Numeric limits
numeric_limits
C numeric limits interface
Runtime type information
Type traits
Primary type categories
is_void (C++11)
is_array (C++11)
is_pointer (C++11)
is_enum (C++11)
is_union (C++11)
is_class (C++11)
is_function (C++11)
is_object (C++11)
is_scalar (C++11)
is_compound (C++11)
is_integral (C++11)
is_floating_point (C++11)
is_fundamental (C++11)
is_arithmetic (C++11)
is_reference (C++11)
is_lvalue_reference (C++11)
is_rvalue_reference (C++11)
is_member_pointer (C++11)
is_member_object_pointer (C++11)
is_member_function_pointer (C++11)
Type properties
is_const (C++11)
is_volatile (C++11)
is_pod (C++11)
is_empty (C++11)
is_polymorphic (C++11)
is_abstract (C++11)
Supported operations
is_constructible
is_trivially_constructible
is_nothrow_constructible
(C++11)
(C++11)
(C++11)
is_default_constructible
is_trivially_default_constructible
is_nothrow_default_constructible
(C++11)
(C++11)
(C++11)
is_copy_constructible
is_trivially_copy_constructible
is_nothrow_copy_constructible
(C++11)
(C++11)
(C++11)
is_move_constructible
is_trivially_move_constructible
is_nothrow_move_constructible
(C++11)
(C++11)
(C++11)
is_assignable
is_trivially_assignable
is_nothrow_assignable
(C++11)
(C++11)
(C++11)
is_copy_assignable
is_trivially_copy_assignable
is_nothrow_copy_assignable
(C++11)
(C++11)
(C++11)
is_move_assignable
is_trivially_move_assignable
is_nothrow_move_assignable
(C++11)
(C++11)
(C++11)
is_destructible
is_trivially_destructible
is_nothrow_destructible
(C++11)
(C++11)
(C++11)
has_virtual_destructor (C++11)
Relationships and property queries
is_same (C++11)
is_base_of (C++11)
is_convertible (C++11)
alignment_of (C++11)
rank (C++11)
extent (C++11)
Type modifications
remove_cv
remove_const
remove_volatile
(C++11)
(C++11)
(C++11)
add_cv
add_const
add_volatile
(C++11)
(C++11)
(C++11)
make_signed (C++11)
make_unsigned (C++11)
Type transformations
aligned_storage (C++11)
aligned_union (C++11)
decay (C++11)
enable_if (C++11)
conditional (C++11)
common_type (C++11)
underlying_type (C++11)
result_of (C++11)
Type trait constants
integral_constant (C++11)
 
Defined in header <type_traits>
template< class... T >
struct common_type;
(since C++11)

Determines the common type among all types T..., that is the type all T... can be implicitly converted to.

  • std::common_type may be specialized for custom types, e.g. std::chrono::time_point.
  • For non-specialized std::common_type, the rules for determining the common type between every pair T1, T2 are exactly the rules for determining the return type of the ternary conditional operator where T1 and T2 are the types of its second and the third operands.
  • For arithmetic types, the common type may also be viewed as the type of the (possibly mixed-mode) arithmetic expression such as T0() + T1() + ... + Tn().

Contents

[edit] Member types

Name Definition
type the common type for all T...

[edit] Specializations

Custom specializations of the type trait std::common_type are allowed. The following specializations are already provided by the standard library:

specializes the std::common_type trait
(class template specialization)
specializes the std::common_type trait
(class template specialization)

[edit] Notes

With a single template argument, std::common_type<T>::type is exactly T, which makes it the C++ equivalent of boost::identity<T>

[edit] Possible implementation

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;
};

[edit] Examples

Demonstrates mixed-mode arithmetic on a user-defined class

#include <iostream>
#include <type_traits>
 
template <class T>
struct Number { T n; };
 
template <class T, class U>
Number<typename std::common_type<T, U>::type> operator+(const Number<T>& lhs,
                                                        const Number<U>& rhs) 
{
    return {lhs.n + rhs.n};
}
 
int main()
{
    Number<int> i1 = {1}, i2 = {2};
    Number<double> d1 = {2.3}, d2 = {3.5};
    std::cout << "i1i2: " << (i1 + i2).n << "\ni1d2: " << (i1 + d2).n << '\n'
              << "d1i2: " << (d1 + i2).n << "\nd1d2: " << (d1 + d2).n << '\n';
}

Output:

i1i2: 3
i1d2: 4.5
d1i2: 4.3
d1d2: 5.8

Demonstrates the use as the identity template

#include <type_traits>
#include <vector>
#include <iostream>
 
template <size_t N>
void fun(const int (&a)[N])
{
    std::cout << "Array overload: ";
    for (int n: a)
        std::cout << n << ' ';
    std::cout << '\n';
}
 
void fun(const std::vector<int>& v)
{
    std::cout << "Vector overload: ";
    for (int n: v)
        std::cout << n << ' ';
    std::cout << '\n';
}
 
int main()
{
    fun( {1, 2, 3} ); // calls the vector overload
    fun( std::common_type<int[]>::type {1, 2, 3} ); // calls the array overload
}

Output:

Vector overload: 1 2 3 
Array overload: 1 2 3