2011-02-09 12 views
68

Non capisco, mi sembra che la chiamata a f sia completamente non ambigua, ma non riesce a compilare con expected primary-expression before ‘int’. Se commento la linea con la chiamata a f, compila bene.Perché viene visualizzato un errore durante il tentativo di richiamare una funzione membro modello con un parametro di tipo esplicito?

template<typename T> 
struct A { 
    template<typename S> 
    void f() { } 
}; 

template<typename T> 
struct B : A<T> { 
    void g() { 
     this->f<int>(); 
    } 
}; 
+29

Mi congratulo per non aver trovato solo questo problema diabolico, ma per non averlo giurato una volta mentre lo descrivevo. –

risposta

129

Ciò è dovuto ad una realtà oscura disposizione dello standard in cui se si dispone di un modello che tenta di accedere a una funzione template in un oggetto il cui tipo dipende da un argomento di un template, è necessario utilizzare la parola chiave template in un modo strano:

this->template f<int>(); 

Questo è simile alla stranezza con typename che esce con tipi dipendenti, tranne l'applicazione di funzioni. In particolare, se si lascia fuori la parola chiave template, c'è un'ambiguità parsing tra

this->f<int>() 

(quelli desiderati), e

((this->f) < int) >() 

che non ha senso (da qui il vostro errore). L'uso della parola chiave template qui disambigura e costringe il compilatore a riconoscere che sta guardando una chiamata perfettamente valida a una funzione membro basata su modelli piuttosto che una massa di simboli confusi.

Spero che questo aiuti!

+2

Conoscevo già alcune stranezze di sintassi con i modelli, ma non ne avevo mai sentito parlare prima. – Gorpik

+0

@Gorpik: ecco perché è necessario evitare tali cose :) – akira

+1

@templatetypedef: sai se un compilatore lo diagnostica correttamente? Sarebbe interessante vedere se CLang (che richiede una diagnosi amichevole) suggerirebbe l'inserimento di 'template' come suggerimento Fix, sfortunatamente non ce l'ho a portata di mano. –

Problemi correlati