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 decaimiento no se aplican.
Además, existe el tipo de función en C++, pero no el tipo de función de miembro. De modo que puede usar una función en lugares donde se espera un puntero a función, pero no puede usar una función de miembro porque no existe tal cosa, solo la función de puntero a miembro. f en tu ejemplo es una función. Por otro lado, 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 cuanto a la resolución de sobrecarga se refiere
Edición aclarar mi respuesta:
Cada expresión en C++ tiene un tipo y un valor. Un valor de un tipo puede ocasionalmente convertirse a un valor de otro tipo. Estas conversiones se clasifican de manera que para hacer una conversión mejor que otra, principalmente para la resolución de sobrecarga de función.
Uno de los tipos de conversiones se llama conversión lvalue-a-rvalue. Cuando aparece un valor l en un contexto donde se requiere un valor r, 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 valor-I, pero se necesita un rvalue aquí, así que j se convierte en un valor de lado derecho. Pero esta no es una conversión observable, ¿verdad? Pero hay casos en los que se puede observar la conversión lvalue-r-value. Es decir, un 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 un lvalue de tipo "función con la firma S" un rvalue del tipo "puntero a función con la firma S" cuyo valor es la dirección de la función
eso significa que cuando asignamos una función a una función de puntero a la función lvalue está implícitamente convirtió en 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 miembros. Estoy hablando, por supuesto, de funciones no estáticas. Las funciones estáticas funcionan de la misma manera que las funciones normales, es decir, no es necesario escribir &X::f
, sino que puede escribir X::f
¿Por qué? Porque X :: f tiene una función de tipo y se lleva a cabo la conversión mencionada. Si f no es estático, sin embargo, X :: f es de tipo ... ¿qué? Ah, sí, no tiene un tipo y, por lo tanto, no es una expresión y, por lo tanto, no tiene valor y, por lo tanto, ese valor no se puede convertir en nada.
Cita del estándar: 5.3.1 cláusula 3 Un puntero al miembro solo se forma cuando se usa un & explícito y su operando es un id. Calificado no encerrado entre paréntesis. [Nota: es decir, la expresión & (id-calificado), donde el id-calificado está entre paréntesis, no forma una expresión de tipo "puntero al miembro". Tampoco lo hace id-calificado, porque no hay conversión implícita desde un id calificado para una función de miembro no estático al tipo "puntero a función de miembro", ya que existe desde un valor l de tipo de función al tipo "puntero a función" (4.3). Tampoco es & sin id-id un puntero al miembro, incluso dentro del alcance de la clase de id no calificado. ]
Espero que esto haya sido más claro ...
My guess! Sería ambiguo, porque 'Fred :: f' también puede significar una variable estática en la clase. – AraK
+1 para una pregunta no estúpida – fredoverflow
@FredOverflow: gracias;) –