2011-12-29 15 views
12

È sicuro assumere che due puntatori di funzione, che puntano a istanze diverse di una funzione basata su un modello, si confronteranno ineguali? Anche se la funzione di modello non usa affatto i parametri del template e quindi la stessa identica cosa in ogni caso?I puntatori a diverse istanze di una funzione basata su modelli sono garantiti per il confronto ineguale?

Ad esempio, il seguente funziona bene sul mio compilatore, ma non sono sicuro se lo fa su qualsiasi altro:

class TypeChecker 
{ 
public: 
    template< typename T > static void foo(void) 
    {} 
    template< typename T > static void setType(void) 
    { s_fooPtr = &foo<T>; } 
    template< typename T > static bool checkType(void) 
    { return (s_fooPtr == &foo<T>); } 
private: 
    static void (* s_fooPtr)(void); 
}; 

void (* TypeChecker::s_fooPtr)(void) = 0; 

int main(void) 
{ 
    TypeChecker::setType<char>(); 
    TypeChecker::checkType<char>();   // true 
    TypeChecker::checkType< unsigned char >(); // false 
    TypeChecker::checkType< signed char >(); // false 
} 

risposta

10

Quando sarà a due puntatori confrontare uguali?

Secondo 5.10/1:

Il == (uguale a) e = (non uguale a) gli operatori hanno le stesse restrizioni semantiche, conversioni e tipo di risultato come relazionale operatori eccetto per la loro precedenza più bassa e il risultato del valore di verità. [ Nota: a<b == c<d è true ogni volta che a<b e c<d hanno lo stesso valore di verità. -end note] I puntatori dello stesso tipo (dopo le conversioni puntatore) possono essere confrontati per l'uguaglianza. Due puntatori dello stesso tipo sono uguali se sono e solo se entrambi sono nulli, puntano entrambi alla stessa funzione, o entrambi rappresentano lo stesso indirizzo (3.9.2).

Sono foo<int>() e foo<char>() la stessa funzione?

Secondo 14,4/1:

Due template-ids si riferiscono alla stessa classe o funzione se

  • loro modello nomi, operatore-funzione-ID, o letterale-operator -ids riferiscono allo stesso modello e
  • loro corrispondenti tipo modello-argomenti sono dello stesso tipo e
  • loro correspo Nding non argomenti di tipo template di tipo integrale o censimento hanno valori identici e
  • loro corrispondenti non di tipo template-argomenti di tipo puntatore riferiscono allo stesso oggetto esterno o funzione o sono entrambi il valore del puntatore nullo e
  • i corrispondenti argomenti modello non di tipo puntatore-membro fanno riferimento allo stesso membro di classe o sono entrambi il valore del puntatore membro nullo e
  • i corrispondenti argomenti modello non di tipo di riferimento fanno riferimento allo stesso esterno oggetto o funzione e
  • il loro modello corrispondente gli argomenti modello si riferiscono allo stesso modello.

Quindi, apparentemente foo<int>() e foo<char>() non sono la stessa funzione.

Quindi &foo<int>() e &foo<char>() non devono essere paragonati, qualunque sia l'ottimizzazione.


EDIT:

Come indicato dal @SergeDundich nel commento, 14,4/1 usato if invece if and only if, che dà alcuna garanzia se foo<int>() e foo<char>() sono la stessa funzione o meno. In altre parti della specifica, if and only if viene utilizzato molto.

Non ho trovato alcun chiarimento a questo nelle specifiche. Tuttavia, negli esempi, posso trovare questo:

template<class T, void(*err_fct)()> class list { /* ... */ }; 
list<int,&error_handler1> x1; 
list<int,&error_handler2> x2; 
list<int,&error_handler2> x3; 
list<char,&error_handler2> x4; 

dichiara x2 e x3 per essere dello stesso tipo. Il loro tipo differisce da dai tipi di x1 e x4.


EDIT2:

if è usato al posto del if and only if esista una simile situazione: (Esempio da 14.5.7/2)

template<class T> struct Alloc { /* ... */ }; 
template<class T> using Vec = vector<T, Alloc<T>>; 
Vec<int> v; // same as vector<int, Alloc<int>> v; 

Vec<int> e vector<int, Alloc<int>> hanno un sacco di differenze, ma sempre dello stesso tipo.

Tuttavia, per quanto riguarda il caso di foo<int>() e foo<char>(), le loro firme sono diverse. Le diverse firme dovrebbero renderle diverse funzioni.

Grazie a @ JohannesSchaub-litb.

+0

E a proposito di "funzioni" in 3.9.2? Quella formulazione implica in qualche modo una funzione è un oggetto con un indirizzo. – sharptooth

+1

@fefe: "Due ID modello si riferiscono alla stessa classe o funzione ** se **" Ma non "se e solo se". Hai notato questo? IMO Questo è molto importante. E IMO la tua conclusione che "' pippo () 'e' pippo () 'non sono la stessa funzione" è sbagliato. Ovviamente non è richiesto dallo standard di essere la stessa funzione, ma le tue quotazioni non dimostrano che hanno richiesto ** di essere la stessa funzione **. –

+0

@sharptooth: in 3.9.2/2, i puntatori sono divisi in 'tipo puntatore oggetto 'e' tipo puntatore funzione'. Il tipo di puntatore dell'oggetto è definito come "il tipo di ** puntatore a ** void o ** un puntatore a ** un tipo di oggetto è chiamato un tipo di puntatore oggetto.", Tuttavia "Il tipo di puntatore che può ** designare ** una funzione è chiamata un tipo di puntatore a funzione. " Sembra che la specifica stia evitando l'uso di "puntatore a" per il puntatore di funzione. E in ultimo, solo il tipo di puntatore dell'oggetto è detto "rappresenta l'indirizzo di un byte in memoria (1.7) o un puntatore nullo (4.10) .'. – fefe

Problemi correlati