El puntero de referencia lleva a usar el valor del objeto indirectamente. Pero nunca he entendido realmente qué significa "usar". Empecé a pensar la pregunta hasta que mi compilador arrojó un error para el siguiente código

int i = 0, *pi = &i;
decltype(*pi) c; // error: 'c' declared as reference but not initialized.

Miré el error durante mucho tiempo y busqué algunas preguntas, solo puedo dar los siguientes argumentos. No sé si son correctos o no.

Argumentos 1:

1) *p es una expresión que no es una variable (o expresión no variable)

2) la expresión de puntero de desreferenciación produce una referencia, de hecho estamos usando una referencia para acceder al valor del objeto

Argumentos 2:

La expresión de referencia solo para la cual decltype devuelve una referencia, no es un caso general

Señala cualquier incorrección o descripción inexacta de los argumentos anteriores.

9
SLN 22 ene. 2018 a las 21:58

3 respuestas

La mejor respuesta

Al desreferenciar un puntero se obtiene una expresión de valor del tipo apuntado que designa el objeto o función señalada. No produce una referencia. * *pi es un valor de tipo int.

decltype (con una excepción no relevante aquí) informa tanto el tipo de una expresión como su categoría de valor , este último está codificado con tipos de referencia. Dado que *pi es un valor de l, está codificado como un tipo de referencia de valor de l, por lo que decltype(*pi) es int &: int para el tipo, & para la categoría de valor.

Las expresiones nunca tienen un tipo de referencia porque cualquier referencia se ajusta "antes de cualquier análisis posterior".


* Esta no es una distinción meramente técnica: según la dirección de problema central 232 y problema principal 453, hay expresiones de desreferencia válidas que puede escribir donde vincular su resultado a una referencia causaría un comportamiento indefinido.

14
T.C. 22 ene. 2018 a las 19:14

De hecho, el estándar dice lo siguiente en 8.5.2.1:

El operador unario * realiza indirectamente: la expresión a la que se aplica será un puntero a un tipo de objeto, o un puntero a un tipo de función y el resultado es un valor l que se refiere al objeto o función al que apunta la expresión. Si el tipo de la expresión es "puntero a T", el tipo del resultado es "T".

Por lo tanto, no es la referencia, pero decltype() le ofrece algo que en realidad tiene una representación en el sistema de tipos C ++, y la referencia es lo más parecido.

3
SergeyA 22 ene. 2018 a las 19:11

Para responder a su pregunta sobre el título: como T.C. respondió también, no. Las expresiones nunca tienen tipo de referencia. Dado un int a; int &b = a;, tanto la expresión a como la expresión b tienen el tipo int, y ambas expresiones son valores.

1) *p es una expresión que no es una variable (o expresión no variable)

Correcta.

2) la expresión de puntero de desreferenciación produce una referencia, de hecho estamos usando una referencia para acceder al valor del objeto

Anular la referencia a un puntero proporciona un valor de l, que decltype cambia a una referencia de valor de l.

la expresión de desreferencia solo para la cual decltype devuelve una referencia, no es un caso general

No estoy completamente seguro de lo que quieres decir aquí. Si quiere decir que cuando decltype no produce una referencia, tener una declaración decltype(...) c; sin un inicializador puede ser válido, entonces sí, de hecho. Si quiere decir que, aparte de los punteros desreferenciados, decltype nunca produce un tipo de referencia, entonces no. Por ejemplo,

int a;
decltype((a)) b; // not okay - decltype((a)) is int & because (a) is not the name of the
                 // variable, and the expression (a) is an lvalue
decltype(a) c;   // okay - decltype(a) is int because a is the name of the variable
decltype(+a) d;  // okay - decltype(+a) is int because the +a is a prvalue of type int
4
user743382user743382 22 ene. 2018 a las 19:11
48388510