Namespaces
Variants

std:: common_reference

From es.cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
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_reference
(C++20)
(C++11)
(C++17)
Compile-time rational arithmetic
Compile-time integer sequences
Definido en el encabezado <type_traits>
template < class ... T >
struct common_reference ;
(desde C++20)

Determina el tipo de referencia común de los tipos T... , es decir, el tipo al que todos los tipos en T... pueden ser convertidos o vinculados. Si existe tal tipo (determinado de acuerdo con las reglas siguientes), el miembro type nombra ese tipo. De lo contrario, no existe el miembro type . El comportamiento es indefinido si alguno de los tipos en T... es un tipo incompleto que no sea (posiblemente calificado cv) void .

Cuando se proporcionan tipos de referencia, common_reference intenta encontrar un tipo de referencia al cual todos los tipos de referencia suministrados puedan enlazarse, pero puede devolver un tipo no referencia si no puede encontrar dicho tipo de referencia.

  • Si sizeof... ( T ) es cero, no existe el miembro type .
  • Si sizeof... ( T ) es uno (es decir, T... contiene solo un tipo T0 ), el miembro type denota el mismo tipo que T0 .
  • Si sizeof... ( T ) es dos (es decir, T... contiene dos tipos T1 y T2 ):
    • Sea el tipo S el tipo de referencia común simple de T1 y T2 (como se define a continuación). El tipo miembro type denota S si se satisfacen todas las condiciones siguientes:
      • T1 y T2 son ambos tipos referencia
      • S está bien formado
(desde C++23)
  • De lo contrario, si std :: basic_common_reference < std:: remove_cvref_t < T1 > , std:: remove_cvref_t < T2 > , T1Q, T2Q > :: type existe, donde TiQ es una plantilla de alias unaria tal que TiQ < U > es U con la adición de los calificadores cv y de referencia de Ti , entonces el tipo miembro type denomina ese tipo;
    • De lo contrario, si decltype ( false ? val < T1 > ( ) : val < T2 > ( ) ) , donde val es una plantilla de función template < class T > T val ( ) ; , es un tipo válido, entonces el miembro type denomina ese tipo;
    • De lo contrario, si std:: common_type_t < T1, T2 > es un tipo válido, entonces el miembro type denomina ese tipo;
    • De lo contrario, no existe el miembro type .
  • Si sizeof... ( T ) es mayor que dos (es decir, T... consiste en los tipos T1, T2, R... ), entonces si std :: common_reference_t < T1, T2 > existe, el miembro type denota std :: common_reference_t < std :: common_reference_t < T1, T2 > , R... > si tal tipo existe. En todos los demás casos, no existe el miembro type .

El tipo de referencia común simple de dos tipos de referencia T1 y T2 se define de la siguiente manera:

  • Si T1 es cv1 X& y T2 es cv2 Y& (es decir, ambos son tipos de referencia lvalue): su tipo de referencia común simple es decltype ( false ? std:: declval < cv12 X & > ( ) : std:: declval < cv12 Y & > ( ) ) , donde cv12 es la unión de cv1 y cv2 , si ese tipo existe y es un tipo de referencia;
  • Si T1 y T2 son ambos tipos de referencia rvalue: si existe el tipo de referencia común simple de T1& y T2& (determinado según el punto anterior), entonces sea C el tipo de referencia rvalue correspondiente a ese tipo. Si std:: is_convertible_v < T1, C > y std:: is_convertible_v < T2, C > son ambos true , entonces el tipo de referencia común simple de T1 y T2 es C ;
  • De lo contrario, uno de los dos tipos debe ser un tipo de referencia lvalue A& y el otro debe ser un tipo de referencia rvalue B&& ( A y B pueden estar calificados con cv). Sea D el tipo de referencia común simple de A & y B const & , si existe. Si D existe y std:: is_convertible_v < B && , D > es true , entonces el tipo de referencia común simple es D ;
  • De lo contrario, no existe tipo de referencia común simple.

Consulte Operador condicional para la definición del tipo de expresión false ? X : Y como las utilizadas anteriormente.

Contenidos

Tipos de miembros

Nombre Definición
type el tipo de referencia común para todos T...

Tipos auxiliares

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

La plantilla de clase basic_common_reference es un punto de personalización que permite a los usuarios influir en el resultado de common_reference para tipos definidos por el usuario (típicamente referencias proxy). La plantilla principal está vacía.

Especializaciones

Un programa puede especializar std :: basic_common_reference < T, U, TQual, UQual > en los dos primeros parámetros T y U si std:: is_same_v < T, std:: decay_t < T >> y std:: is_same_v < U, std:: decay_t < U >> son ambos true y al menos uno de ellos depende de un tipo definido por el programa.

Si tal especialización tiene un miembro llamado type , debe ser un miembro público y no ambiguo que nombre un tipo al cual tanto TQual < T > como UQual < U > sean convertibles. Adicionalmente, std :: basic_common_reference < T, U, TQual, UQual > :: type y std :: basic_common_reference < U, T, UQual, TQual > :: type deben denotar el mismo tipo.

Un programa no puede especializar basic_common_reference en el tercer o cuarto parámetro, ni puede especializar common_reference mismo. Un programa que añade especializaciones violando estas reglas tiene comportamiento indefinido.

La biblioteca estándar proporciona las siguientes especializaciones de basic_common_reference :

determina el tipo de referencia común de dos pair s
(especialización de plantilla de clase)
determina el tipo de referencia común de un tuple y un tipo tuple-like
(especialización de plantilla de clase)
determina el tipo de referencia común de reference_wrapper y no- reference_wrapper
(especialización de plantilla de clase)

Notas

Macro de prueba de características Valor Estándar Característica
__cpp_lib_common_reference 202302L (C++23) Hacer que std::common_reference_t de std::reference_wrapper sea un tipo referencia

Ejemplos

#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() {}

Véase también

determina el tipo común de un grupo de tipos
(plantilla de clase)
especifica que dos tipos comparten un tipo de referencia común
(concepto)