Domanda

Se la seguente dal C ++ FAQ Lite è vero: "un nome di funzione decadimenti ad un puntatore alla funzione" (come un nome di matrice decade in un puntatore al suo primo elemento); perché dobbiamo includere la e commerciale?

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

E non solo:

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

Nel secondo caso Fred :: f è una funzione e può decadere a un puntatore a tale funzione.

Spero che questa domanda non è così stupido.

È stato utile?

Soluzione

risposta originale:

perché un membro funzione non è una funzione ed un organo-funzione-puntatore non è una funzione del puntatore. Pertanto non si applicano le regole di decadimento.

Inoltre, c'è tipo di funzione in C ++, ma non Tipo di utente-funzione. Così si può utilizzare una funzione in luoghi in cui si prevede una funzione di puntatore a, ma non è possibile utilizzare un membro funzione perché non v'è nulla di simile, solo puntatore-a-membro-funzione. 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 concerne

Modifica per chiarire la mia risposta:

Ogni espressione in C ++ ha un tipo e valore. Un valore di un tipo occasionalmente può essere convertito in un valore di un altro tipo. Queste conversioni sono classificati in modo da rendere una conversione migliore che un'altra principalmente per la risoluzione funzione di sovraccarico.

Uno dei tipi di conversioni è chiamato Ivalue a rvalue conversione. Quando un Ivalue appare in un contesto in cui è richiesta una rvalue questa conversione avviene. Di solito questo tipo di conversione non fa nulla, per esempio:

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

sulla seconda riga j è un lvalue, ma è necessario un rvalue qui, così j viene convertito in un rvalue. Ma questa non è una conversione osservabile, è vero? Ma ci sono casi in cui si può osservare la conversione lvalue-to-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 < em> un lvalue di tipo "funzione con la 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 di puntatore a funzione lvalue è implicitamente convertito ad esso di indirizzo.

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

f è un'espressione e ha un tipo. Tipo di f è void()

Non v'è alcun tale tipo in C ++ come member-function Ci sono puntatori-a-membri-funzioni, ma non le funzioni di membro stessi. Sto parlando, naturalmente, sulle funzioni non statici. funzioni statiche funzionano allo stesso modo come funzioni ordinarie, vale a dire, non si dispone di &X::f scrittura, invece è possibile scrivere X::f Perché? Poiché X :: f ha una funzione di tipo e la conversione suddetto avviene. Se f è non statico, tuttavia, X :: f è di tipo ... che cosa? Oh sì, non ha un tipo e quindi non è espressione e quindi non hanno un valore e, pertanto, tale valore non può essere convertito a nulla.

Citazione dalla norma: 5.3.1 comma 3 Un puntatore a membro si forma solo quando viene utilizzato un esplicito & e il suo operando è un qualificato-id non racchiuso tra parentesi. [Nota: che è l'espressione e (qualificato-id), dove la qualificata id è racchiuso tra parentesi, non forma un'espressione di tipo “puntatore a membri.” Nemmeno qualificata-id, perché non v'è alcuna conversione implicita da un qualificato-id per una funzione membro non statica del tipo “puntatore a funzione membro” in quanto v'è da un lvalue di tipo funzione al tipo “puntatore a funzione” (4.3). Né e qualificato-id un puntatore a membro, anche nell'ambito della La classe di non qualificata-id. ]

Spero che questo è stato più chiaro ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top