2010-10-24 25 views
15

Se le seguenti domande del C++ Lite sono vere: "il nome di una funzione decadono in un puntatore alla funzione" (come il nome di un array decadde in un puntatore al suo primo elemento); perché dobbiamo includere la e commerciale?Puntatore funzione membro

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 quella funzione.

Spero che questa domanda non sia così stupida.

+0

La mia ipotesi! Sarebbe ambiguo, perché 'Fred :: f' può anche significare una variabile statica nella classe. – AraK

+1

+1 per una domanda non stupida – fredoverflow

+0

@FredOverflow: grazie;) –

risposta

16

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 ...

+0

"Esiste un tipo di funzione in C++, ma non un tipo di funzione membro." -> Cosa intendi esattamente con questo? Sicuramente 'FredMemFn' ha un tipo? – fredoverflow

+0

@FredOverflow: Sì, FredMemFn ha un tipo e quel tipo è "pointer-to-member, incluso di quale classe e di quale firma". Ogni espressione in C++ ha un tipo. Ad esempio se f è una funzione indipendente void f(), il tipo dell'espressione (f) è void() che è un tipo di funzione. D'altra parte l'espressione Fred :: f non è un'espressione perché non ha un tipo. Ma & Fred :: f è un'espressione di tipo pointer-to-member blah blah ... è ciò che intendo –

+0

L'operatore '&' non richiede un'espressione come suo operando? – fredoverflow

Problemi correlati