risposta originale:
perché un membro-funzione non è una funzione e un membro-funzione di puntatore non è una funzione puntatore. Pertanto le regole di decadimento non si applicano.
Inoltre, esiste un tipo di funzione in C++, ma non un tipo di funzione membro. Quindi è possibile utilizzare una funzione in punti in cui è previsto un puntatore alla funzione, ma non è possibile utilizzare una funzione membro poiché non esiste una funzione del tipo puntatore-membro. f nel tuo esempio è una funzione. D'altra parte, Fred :: f è ... beh, niente.
Inoltre, direi che "il nome di una funzione può decadere ...". No, il nome non può fare nulla, un lvalue di tipo funzione può essere convertito in modo implicito una funzione puntatore-a-, e questa è una conversione di identità per quanto riguarda la risoluzione di sovraccarico è interessato
Editing per chiarire la mia risposta:
Ogni espressione in C++ ha un tipo e un valore. Un valore di un tipo può essere occasionalmente convertito in un valore di un altro tipo. Queste conversioni sono classificate in modo tale da rendere una conversione migliore di un'altra principalmente per la risoluzione dell'overload delle funzioni.
Uno dei tipi di conversioni è denominato conversione da lvalue a valore. Quando un lvalue appare in un contesto in cui è richiesto un rvalue questa conversione ha luogo. Solitamente questo tipo di conversione non fa nulla, per esempio:
int i = 4, j = 5;
i = j;
sulla seconda riga j è un lvalue, ma è necessario qui un rvalue, così j viene convertito in un rvalue. Ma questa non è una conversione osservabile, vero? Ma ci sono casi in cui è possibile osservare la conversione da lvalue a rvalue. Cioè, un Ivalue di array di n T può essere convertito in un rvalue di tipo T*
cui valore è l'indirizzo del primo elemento dell'array e un lvalue di tipo "funzione con firma S" un rvalue di tipo "puntatore a funzione con la firma S" il cui valore è l'indirizzo della funzione
ciò significa che quando si assegna una funzione a una funzione puntatore a funzione Ivalue viene convertito implicitamente il suo indirizzo.
f è un'espressione e ha un tipo.tipo di f è void()
Non esiste tipo in C++ come member-function
Ci sono puntatori-a-membri funzioni, ma non funzioni membro stessi. Sto parlando ovviamente delle funzioni non statiche. Le funzioni statiche funzionano allo stesso modo delle funzioni ordinarie, ovvero non è necessario scrivere &X::f
, invece è possibile scrivere X::f
Perché? Perché X :: f ha una funzione di tipo e la conversione di cui sopra ha luogo. Se f è non statico, tuttavia, X :: f è di tipo ... cosa? Oh sì, non ha un tipo e quindi non è un'espressione e quindi non ha valore e quindi quel valore non può essere convertito in nulla.
Citazione dallo standard: 5.3.1 clausola 3 Un puntatore al membro viene creato solo quando viene utilizzato un & esplicito e il suo operando è un id qualificato non racchiuso tra parentesi. [Nota: vale a dire, l'espressione & (id qualificato), in cui l'id qualificato è racchiuso tra parentesi, non forma un'espressione di tipo "puntatore al membro". Né id-qualificato, perché non c'è alcuna conversione implicita da un id qualificato per una funzione membro non statico al tipo "puntatore alla funzione membro" poiché esiste da un lvalue di tipo funzione al tipo "puntatore alla funzione" (4.3). Né è & un ID non qualificato un puntatore al membro, anche nell'ambito della classe di ID non qualificato . ]
Spero che questo sia stato più chiaro ...
La mia ipotesi! Sarebbe ambiguo, perché 'Fred :: f' può anche significare una variabile statica nella classe. – AraK
+1 per una domanda non stupida – fredoverflow
@FredOverflow: grazie;) –