Pregunta

Si la siguiente desde el C ++ FAQ Lite es cierto: "un nombre de función decae a un puntero a la función" (como un nombre de matriz decae a un puntero a su primer elemento); ¿por qué tenemos que incluir el símbolo de unión?

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = &Fred::f;

Y no sólo:

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = Fred::f;

En el segundo caso Fred :: f es una función y puede decaer a un puntero a esa función.

Espero que esta pregunta no es tan estúpida.

¿Fue útil?

Solución

Respuesta original:

debido a una función miembro no es una función y una función triple miembro no es una función triple. Por lo tanto las reglas de la caries no se aplican.

Además, no hay tipo de función en C ++, pero no de tipo función miembro. Así que usted puede utilizar una función en los lugares donde se espera una función puntero a, pero no se puede utilizar una función miembro, porque no hay tal cosa, sólo el puntero a miembro de funciones. f en su ejemplo es una función. Por otra parte, Fred :: f es ... bueno, nada.

Además, yo diría que "el nombre de una función puede decaer ...". No, el nombre no se puede hacer nada, un valor-I de tipo de función se puede convertir implícitamente a una función puntero a, y esto es una conversión de identidad en lo que se refiere a la resolución de sobrecarga

Edición para aclarar mi respuesta:

Cada expresión en C ++ tiene un tipo y valor. Un valor de un tipo de vez en cuando puede ser convertido a un valor de otro tipo. Estas conversiones se clasifican de modo que para hacer una conversión mejor que otro, principalmente para la resolución de sobrecarga de la función.

Uno de los tipos de las conversiones se llama conversión-lvalue-a rvalue. Cuando un valor-i aparece en un contexto en el que se requiere una rvalue esta conversión se lleva a cabo. Por lo general, este tipo de conversión no hace nada, por ejemplo:

int i = 4, j = 5;
i = j;

en la segunda línea j es un lvalue, pero se necesita un rvalue aquí, así j se convierte a un valor p. Pero esto no es una conversión observable, ¿verdad? Sin embargo, hay casos en los que se pueda observar la conversión de valor-i-a rvalue. Es decir, una lvalue de matriz de n T se puede convertir en un valor p de tipo T* cuyo valor es la dirección del primer elemento de la matriz y < em> un valor-I de tipo "función con la firma S", un valor p de tipo "puntero a la función con la firma S" cuyo valor es la dirección de la función

Esto significa que cuando asignamos una función a una función de puntero a la función de valor-I se convierte implícitamente a su dirección.

void f() {}
void (*p) () = f; //f is converted to rvalue

f es una expresión y tiene un tipo. tipo de f es void()

No hay tal tipo en C ++ como un member-function Hay punteros a miembro-funciones, pero no las funciones miembro mismos. Estoy hablando, por supuesto, acerca de las funciones no estáticos. funciones estáticas funcionar de la misma manera que las funciones ordinarias, es decir, que no tiene que &X::f escritura, en lugar usted puede escribir X::f ¿Por qué? Debido a que X :: f tiene una función de tipo y la conversión antes mencionada se lleva a cabo. Si f no es estático, sin embargo, X :: f es de tipo ... ¿qué? Oh sí, que no tiene un tipo y por lo tanto no es una expresión y, por tanto, no tiene valor y por lo tanto que el valor no se puede convertir en cualquier cosa.

Presupuesto de la norma: 5.3.1 cláusula 3 Un puntero al miembro solamente se forma cuando se utiliza una explícita y su operando y es un cualificado-id no se encuentra encerrado entre paréntesis. [Nota: es decir, la expresión y (calificado-id), donde el calificada-id se encierra entre paréntesis, no se forma una expresión del tipo “puntero a miembro.” Tampoco cualificado-id, porque no hay una conversión implícita de un calificado-id para una función miembro no estática a la “puntero a función miembro” tipo ya que es de una lvalue de tipo de función a la “puntero a la función de” tipo (4,3). Tampoco es y sin reservas-id un puntero a miembro, incluso en el ámbito de la La clase de rotundo-id. ]

Espero que esto era más clara ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top