table of contents
std::common_reference(3) | C++ Standard Libary | std::common_reference(3) |
NAME¶
std::common_reference - std::common_reference
Synopsis¶
Defined in header <type_traits>
template< class... T > (since C++20)
struct common_reference;
Determines the common reference type of the types T..., that is, the type to
which
all the types in T... can be converted or bound. 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.
When given reference types, common_reference attempts to find a reference
type to
which the supplied reference types can all be bound, but may return a
non-reference
type if it cannot find such a reference type.
* 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 T0.
* If sizeof...(T) is two (i.e., T... contains two types T1 and T2):
* Let type S be the simple common reference type of T1 and T2 (as defined
below). The member type type names S if all of the conditions below are
satisfied:
* T1 and T2 are both reference types
* S is well-formed
* std::is_convertible_v<std::add_pointer_t<T1>,
std::add_pointer_t<S>> and (since C++23)
std::is_convertible_v<std::add_pointer_t<T2>,
std::add_pointer_t<S>> are true;
* Otherwise, if std::basic_common_reference<std::remove_cvref_t<T1>,
std::remove_cvref_t<T2>, T1Q, T2Q>::type exists, where TiQ is a
unary alias
template such that TiQ<U> is U with the addition of Ti's cv- and
reference
qualifiers, then the member type type names that type;
*
* Otherwise, if decltype(false? val<T1>() : val<T2>()), where val
is a
function template template<class T> T val();, is a valid type, then the
member type type names that type;
* Otherwise, if std::common_type_t<T1, T2> is a valid type, then the
member
type type names that type;
* Otherwise, there is no member type.
* If sizeof...(T) is greater than two (i.e., T... consists of the types T1,
T2,
R...), then if std::common_reference_t<T1, T2> exists, the member type
denotes
std::common_reference_t<std::common_reference_t<T1, T2>, R...> if
such a type
exists. In all other cases, there is no member type.
The simple common reference type of two reference types T1 and T2 is defined
as
follows:
* If T1 is cv1 X& and T2 is cv2 Y& (i.e., both are lvalue reference
types): their
simple common reference type is decltype(false? std::declval<cv12
X&>() :
std::declval<cv12 Y&>()), where cv12 is the union of cv1 and cv2,
if that type
exists and is a reference type;
* If T1 and T2 are both rvalue reference types: if the simple common
reference
type of T1& and T2& (determined according to the previous bullet)
exists, then
let C denote that type's corresponding rvalue reference type. If
std::is_convertible_v<T1, C> and std::is_convertible_v<T2, C> are
both true,
then the simple common reference type of T1 and T2 is C;
* Otherwise, one of the two types must be an lvalue reference type A& and
the
other must be an rvalue reference type B&& (A and B might be
cv-qualified). Let
D denote the simple common reference type of A& and B const&, if any.
If D
exists and std::is_convertible_v<B&&, D> is true, then the
simple common
reference type is D;
* Otherwise, there's no simple common reference type.
See Conditional operator for the definition of the type of expression false ?
X : Y
like the ones used above.
Member types¶
Name Definition
type the common reference type for all T...
Helper types¶
template< class... T >
using common_reference_t = std::common_reference<T...>::type;
template< class T, class U, template<class> class TQual,
template<class> class
UQual >
struct basic_common_reference {};
The class template basic_common_reference is a customization point that
allows users
to influence the result of common_reference for user-defined types (typically
proxy
references). The primary template is empty.
Specializations¶
A program may specialize std::basic_common_reference<T, U,
TQual, UQual> on the
first two parameters T and U if std::is_same_v<T,
std::decay_t<T>> and
std::is_same_v<U, std::decay_t<U>> are both true and at least one
of them depends on
a program-defined type.
If such a specialization has a member named type, it must be a public and
unambiguous member that names a type to which both TQual<T> and
UQual<U> are
convertible. Additionally, std::basic_common_reference<T, U, TQual,
UQual>::type and
std::basic_common_reference<U, T, UQual, TQual>::type must denote the
same type.
A program may not specialize basic_common_reference on the third or fourth
parameters, nor may it specialize common_reference itself. A program that
adds
specializations in violation of these rules has undefined behavior.
The standard library provides following specializations of
basic_common_reference:
determines the common reference
std::basic_common_reference<std::pair> type of two pairs
(C++23) (class template specialization)
determines the common reference
std::basic_common_reference<tuple-like> type of a tuple and a
tuple-like
(C++23) type
(class template specialization)
determines the common reference
std::basic_common_reference<std::reference_wrapper> type of
reference_wrapper and
(C++23) non-reference_wrapper
(class template specialization)
Notes¶
Feature-test macro Value Std Feature
__cpp_lib_common_reference 202302L (C++23) Make std::common_reference_t of
std::reference_wrapper a reference type
Examples¶
// Run this code
#include <concepts>
#include <type_traits>
static_assert(
std::same_as<
int&,
std::common_reference_t<
std::add_lvalue_reference_t<int>,
std::add_lvalue_reference_t<int>&,
std::add_lvalue_reference_t<int>&&,
std::add_lvalue_reference_t<int>const,
std::add_lvalue_reference_t<int>const&
>
>
);
int main() {}
See also¶
common_type determines the common type of a group of types
(C++11) (class template)
common_reference_with specifies that two types share a common reference type
(C++20) (concept)
2024.06.10 | http://cppreference.com |