std::meta::common_type - cppreference.com
Namespaces
Variants

std::meta::common_type

From cppreference.com
< cpp | meta
 
 
 
Reflection library
 
Reflection types and queries
Type properties
Type property queries
 
Defined in header <meta>
template< std::meta::reflection_range R = std::initializer_list<std::meta::info> >
consteval std::meta::info common_type( R&& types );
(since C++26)

Let T... be a pack of types or type aliases whose elements are represented by the corresponding elements of types. Determines the common type among all types T..., that is a type all T... can be explicitly converted to.

If such a type exists (as determined according to the same rules as for std::common_type), returns the reflection of that type.

Equivalent to return std::meta::dealias(^^std::common_type<T...>::type);, except that if the member type is not provided (i.e., the common type does not exist), throws std::meta::exception.

If any type in the pack T... is not a complete type, (possibly cv-qualified) void, or an array of unknown bound, the program is ill-formed.

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 program is ill-formed.

Parameters

types - a range of reflected types

Return value

A reflection of the common type among all types T..., if such a type exists.

Exceptions

Throws std::meta::exception if

  • any reflection in types does not represent a type or type alias;
  • no common type exists, as described above.

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().

Example

#include <iostream>
#include <meta>

static_assert(
    ^^int == std::meta::common_type({^^const int, ^^volatile int}) and
    ^^double == std::meta::common_type({^^int, ^^float, ^^double})
);

template<class T>
struct Number { T n; };

template<class T, class U>
constexpr Number<typename[:std::meta::common_type({^^T, ^^U}):]>
    operator+(const Number<T>& lhs, const Number<U>& rhs)
{
    return {lhs.n + rhs.n};
}

template<typename T>
std::ostream& operator<< (std::ostream& os, Number<T> x)
{
    return os << std::meta::display_string_of(^^Number<T>) << '{' << x.n << '}';
}

int main()
{
    Number<int> i1{1}, i2{2};
    Number<double> d1{2.3}, d2{3.5};

    std::cout << "i1 + i2 == " << i1 + i2 << "\n"
                 "i1 + d2 == " << i1 + d2 << "\n"
                 "d1 + i2 == " << d1 + i2 << "\n"
                 "d1 + d2 == " << d1 + d2 << "\n";
}

Possible output:

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

See also