2012-02-13 12 views
12

Estaba navegando a través de la draft of the C++11 standard y encontró la siguiente declaración desconcertante (§13.6/8):Unario + sobre los punteros de

Para cada tipo T existen funciones de operador candidatos de la forma

T* operator+(T*); 

¿Cómo debe entenderse este operador "unario +" en el puntero? ¿Es esto simplemente una ausencia operativa en el caso normal, que sin embargo puede estar sobrecargada? ¿O hay algún punto más profundo que me falta aquí?

Respuesta

8

La respuesta a su pregunta es sólo una página por encima de la cotización ha citado — §13.6/1:

Las funciones de operador candidato que representan los operadores internos definidos en la Cláusula 5 se especifican en este apartado . Estas funciones candidatas participan en el proceso de resolución de sobrecarga del operador como se describe en 13.3.1.2 y no se utilizan para ningún otro propósito. [Nota: Dado que los operadores incorporados solo toman operandos con tipo no de clase, y la resolución de sobrecarga del operador solo ocurre cuando una expresión de operando originalmente tiene clase o tipo de enumeración, la resolución de sobrecarga del operador puede resolverse solo cuando un operando tiene un tipo de clase que tiene una conversión definida por el usuario a un tipo no de clase apropiado para el operador, o cuando un operando tiene un tipo de enumeración que se puede convertir a un tipo apropiado para el operador. También tenga en cuenta que algunas de las funciones candidatas del operador dadas en esta subcláusula son más permisivas que los propios operadores incorporados. Como se describe en 13.3.1.2, después de seleccionar un operador incorporado por resolución de sobrecarga, la expresión está sujeta a los requisitos para el operador incorporado que se proporciona en la cláusula 5 y, por lo tanto, a cualquier restricción semántica adicional dada allí. Si hay un candidato escrito por el usuario con el mismo nombre y tipos de parámetros que una función candidata incorporada, la función incorporada del operador está oculta y no está incluida en el conjunto de funciones candidatas. -fin nota]

+0

Entonces 'T * operator + (T *);' ¿es miembro o global? y en el caso de lambda -> '+ [] {};' ¿qué es 'T', me pregunto? Gracias –

+0

@ AngelusMortis: los punteros no pueden tener miembros; esto usa el 'operador +' unario incorporado del lenguaje para tipos aritméticos.Y el tipo de '+ [] {}' es 'void (*)()', como unario 'operator +' en lambdas sin captura convierte el lambda en un puntero de función. – ildjarn

+0

Estimado señor, todavía estoy un poco confundido, así que déjame preguntar citando tus declaraciones -> "Los punteros no pueden tener miembros" sí, pero inicialmente pensé que las lambdas se convierten a clases (por compiladores) sobrecargando 'operator()', por lo tanto Pensé que podrían ser miembros. Ahora su afirmación "usa el operador unario' incorporado del lenguaje + 'para tipos aritméticos", estoy seguro de que los tipos aritméticos son básicamente tipos integrales + flotantes, y cómo la expresión -> '+ []()' -> 'operador + (algunos_nombre_no_no_I_don 't_know) '-> se convierte en' void (*)() ' –

0

Bueno, podrías sobrecargarlo, haz lo que quieras, pero está justo para la simetría con el operador unario. Como mencionas, es solo un no-operador la mayor parte del tiempo.

+3

¿podría usted? _operador debe tener un argumento de clase o tipo enumerado_? – Lol4t0

8

El + sobre los punteros es un NOOP excepto para cambiar las cosas a rvalues. A veces es útil si quieres a decaer matrices o funciones

int a[] = { 1, 2, 3 }; 
auto &&x = +a; 

Ahora x es un int*&& y no un int(&)[3]. Si desea pasar x o +a a plantillas, esta diferencia puede ser importante. a + 0 no siempre es equivalente, considere

struct forward_decl; 
extern forward_decl a[]; 
auto &&x = +a; // well-formed 
auto &&y = a + 0; // ill-formed 

se forma mal La última línea, ya que agregar nada a un puntero requiere del puntero puntas de tipo de clase a ser completamente definida (ya que avanza por sizeof(forward_decl) * N bytes).

+0

no es esto lo que 'std :: move()' y 'std :: forward()' pretende hacer? Entonces, si entiendo esto correctamente '+ a' y 'std :: move (a)' harían lo mismo? – LiKao

+1

@LiKao en absoluto. 'move' conserva el tipo, pero simplemente cambia la categoría del valor. Así' move (a) 'daría un rvalue de escriba 'int [3]', no un valor de r de tipo 'int *'. Ahora aplicar 'move' a una función no hace nada en absoluto (convertir a' FunctionType && 'produce un valor l) y no es particularmente significativo I pensar. –

+0

@LiKao: No, 'std :: move' conserva la matriz, mientras que unary + la descompone (y produce un puntero rvalue). – Xeo

Cuestiones relacionadas