Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::common_type

      From cppreference.com
      <cpp‎ |types
       
       
      Metaprogramming library
      Type traits
      Type categories
      (C++11)
      (C++11)(DR*)
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      (C++11)
      (C++11) 
      Type properties
      (C++11)
      (C++11)
      (C++14)
      (C++11)(deprecated in C++26)
      (C++11)(until C++20*)
      (C++11)(deprecated in C++20)
      (C++11)
      Type trait constants
      Metafunctions
      (C++17)
      Supported operations
      Relationships and property queries
      Type modifications
      Type transformations
      (C++11)(deprecated in C++23)
      (C++11)(deprecated in C++23)
      (C++11)
      (C++11)(until C++20*)(C++17)

      common_type
      (C++11)
      (C++11)
      (C++17)
      Compile-time rational arithmetic
      Compile-time integer sequences
       
      Defined in header<type_traits>
      template<class...T>
      struct common_type;
      (since C++11)

      Determines the common type among all typesT..., that is a type allT... can be explicitly converted to. If such a type exists (as determined according to the rules below), the membertype names that type. Otherwise, there is no membertype.

      • Ifsizeof...(T) is zero, there is no membertype.
      • Ifsizeof...(T) is one (i.e.,T... contains only one typeT0), the membertype names the same type asstd::common_type<T0, T0>::type if it exists; otherwise there is no membertype.
      • Ifsizeof...(T) is two (i.e.,T... contains exactly two typesT1 andT2),
      • If applyingstd::decay to at least one ofT1 andT2 produces a different type, the membertype names the same type asstd::common_type<std::decay<T1>::type,std::decay<T2>::type>::type, if it exists; if not, there is no membertype;
      • Otherwise, if there is a user specialization forstd::common_type<T1, T2>, that specialization is used;
      • Otherwise, ifstd::decay<decltype(false?std::declval<T1>():std::declval<T2>())>::type is a valid type, the membertype denotes that type, seethe conditional operator;
      (since C++20)
      • Otherwise, there is no membertype.
      • Ifsizeof...(T) is greater than two (i.e.,T... consists of the typesT1, T2, R...), then ifstd::common_type<T1, T2>::type exists, the membertype denotesstd::common_type<typename std::common_type<T1, T2>::type, R...>::type if such a type exists. In all other cases, there is no membertype.

      If any type in the parameter packT is not a complete type, (possibly cv-qualified)void, or an array of unknown bound, the behavior is undefined.

      If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the behavior is undefined.

      Contents

      [edit]Nested types

      Name Definition
      type the common type for allT

      [edit]Helper types

      template<class...T>
      using common_type_t=typename common_type<T...>::type;
      (since C++14)

      [edit]Specializations

      Users may specializecommon_type for typesT1 andT2 if

      • At least one ofT1 andT2 depends on a user-defined type, and
      • std::decay is an identity transformation for bothT1 andT2.

      If such a specialization has a member namedtype, it must be a public and unambiguous member that names a cv-unqualified non-reference type to which bothT1 andT2 are explicitly convertible. Additionally,std::common_type<T1, T2>::type andstd::common_type<T2, T1>::type must denote the same type.

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

      Note that the behavior of a program that adds a specialization to any other template(except forstd::basic_common_reference)(since C++20) from<type_traits> is undefined.

      The following specializations are already provided by the standard library:

      specializes thestd::common_type trait
      (class template specialization)[edit]
      specializes thestd::common_type trait
      (class template specialization)[edit]
      determines the common type of twopairs
      (class template specialization)[edit]
      determines the common type of atuple and atuple-like type
      (class template specialization)[edit]
      determines the common type of an iterator and an adaptedbasic_const_iterator type
      (class template specialization)[edit]

      [edit]Possible implementation

      // primary template (used for zero types)template<class...>struct common_type{}; // one typetemplate<class T>struct common_type<T>: common_type<T, T>{}; namespace detail{template<class...>using void_t=void; template<class T1,class T2>using conditional_result_t= decltype(false?std::declval<T1>():std::declval<T2>()); template<class,class,class=void>struct decay_conditional_result{};template<class T1,class T2>struct decay_conditional_result<T1, T2, void_t<conditional_result_t<T1, T2>>>:std::decay<conditional_result_t<T1, T2>>{}; template<class T1,class T2,class=void>struct common_type_2_impl: decay_conditional_result<const T1&,const T2&>{}; // C++11 implementation:// template<class, class, class = void>// struct common_type_2_impl {}; template<class T1,class T2>struct common_type_2_impl<T1, T2, void_t<conditional_result_t<T1, T2>>>: decay_conditional_result<T1, T2>{};} // two typestemplate<class T1,class T2>struct common_type<T1, T2>:std::conditional<std::is_same<T1,typenamestd::decay<T1>::type>::value&&std::is_same<T2,typenamestd::decay<T2>::type>::value,                       detail::common_type_2_impl<T1, T2>,                       common_type<typenamestd::decay<T1>::type,typenamestd::decay<T2>::type>>::type{}; // 3+ typesnamespace detail{template<class AlwaysVoid,class T1,class T2,class...R>struct common_type_multi_impl{};template<class T1,class T2,class...R>struct common_type_multi_impl<void_t<typename common_type<T1, T2>::type>, T1, T2, R...>: common_type<typename common_type<T1, T2>::type, R...>{};} template<class T1,class T2,class...R>struct common_type<T1, T2, R...>: detail::common_type_multi_impl<void, T1, T2, R...>{};

      [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 asT0()+ T1()+ ...+ Tn().

      [edit]Examples

      Demonstrates mixed-mode arithmetic on a program-defined class:

      Run this code
      #include <iostream>#include <type_traits> template<class T>struct Number{ T n;}; template<class T,class U>constexpr Number<std::common_type_t<T, U>>    operator+(const Number<T>& lhs,const Number<U>& rhs){return{lhs.n+ rhs.n};} void describe(constchar* expr,const Number<int>& x){std::cout<< expr<<"  is  Number<int>{"<< x.n<<"}\n";} void describe(constchar* expr,const Number<double>& x){std::cout<< expr<<"  is  Number<double>{"<< x.n<<"}\n";} int main(){    Number<int> i1={1}, i2={2};    Number<double> d1={2.3}, d2={3.5};    describe("i1 + i2", i1+ i2);    describe("i1 + d2", i1+ d2);    describe("d1 + i2", d1+ i2);    describe("d1 + d2", d1+ d2);}

      Output:

      i1 + i2  is  Number<int>{3}i1 + d2  is  Number<double>{4.5}d1 + i2  is  Number<double>{4.3}d1 + d2  is  Number<double>{5.8}

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 2141C++11the result type of the conditional operator was not decayeddecayed the result type
      LWG 2408C++11common_type was not SFINAE-friendlymade SFINAE-friendly
      LWG 2460C++11common_type specializations were nearly impossible to writereduced the number of
      specializations needed

      [edit]See also

      specifies that two types share a common type
      (concept)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/types/common_type&oldid=180922"

      [8]ページ先頭

      ©2009-2025 Movatter.jp