< cpp‎ | experimental‎ | ranges
Technical Specification
Filesystem library (filesystem TS)
Library fundamentals (library fundamentals TS)
Library fundamentals 2 (library fundamentals TS v2)
Library fundamentals 3 (library fundamentals TS v3)
Extensions for parallelism (parallelism TS)
Extensions for parallelism 2 (parallelism TS v2)
Extensions for concurrency (concurrency TS)
Extensions for concurrency 2 (concurrency TS v2)
Concepts (concepts TS)
Ranges (ranges TS)
Reflection (reflection TS)
Mathematical special functions (special functions TR)
Experimental Non-TS
Pattern Matching
Linear Algebra
2D Graphics
General utilities library
Utility components
Function objects
Metaprogramming and type traits
Tagged pairs and tuples
tag specifiers
template< class... T >
struct common_type;
(ranges TS)

Determines the common type among all types T..., that is the type all T... can be implicitly converted to. If such a type exists (as determined according to the rules below), the member type names that type. Otherwise, there is no member type. The behavior is undefined if any of the types in T... is an incomplete type other than (possibly cv-qualified) void.

  • If sizeof...(T) is zero, there is no member type.
  • If sizeof...(T) is one (i.e., T... contains only one type T0), the member type names the same type as std::decay_t<T0>.
  • If sizeof...(T) is two (i.e., T... contains exactly two types T1 and T2),
  • If applying std::decay to at least one of T1 and T2 produces a different type, the member type names the same type as ranges::common_type_t<std::decay_t<T1>, std::decay_t<T2>>, if it exists; if not, there is no member type;
  • Otherwise, (and unless there is a user specialization for ranges::common_type<T1, T2>), if std::common_type_t<T1, T2> is well-formed, then the member type denotes that type;
  • Otherwise, the member type denotes the type std::decay_t<decltype(false ? std::declval<const T1&>() : std::declval<const T2&>())>, if that conditional expression is well-formed; if not, there is no member type.
  • If sizeof...(T) is greater than two (i.e., T... consists of the types T1, T2, R...), then if ranges::common_type_t<T1, T2> exists, the member type denotes ranges::common_type_t<ranges::common_type_t<T1, T2>, R...> if such a type exists. In all other cases, there is no member type.


[edit] Member types

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

[edit] Helper types

template< class... T >
using common_type_t = typename common_type<T...>::type;

[edit] Specializations

Users may specialize common_type for types T1 and T2 if

  • At least one of T1 and T2 depends on a user-defined type, and
  • std::decay is an identity transformation for both T1 and T2.

If such a specialization has a member named type, it must be a public and unambiguous member type that names a cv-unqualified non-reference type to which both T1 and T2 are explicitly convertible. Additionally, ranges::common_type_t<T1, T2> and ranges::common_type_t<T2, T1> must denote the same type.

A program that adds common_type specializations in violation of these rules has undefined behavior.

[edit] Notes

For arithmetic types not subject to promotion, the common type may be viewed as the type of the (possibly mixed-mode) arithmetic expression such as T0() + T1() + ... + Tn().

[edit] Example

[edit] See also

determines the common type of a group of types
(class template) [edit]
determine the common reference type of a set of types
(class template) [edit]