2011-02-09 6 views
68

Nie rozumiem, wydaje mi się, że wywołanie f jest całkowicie jednoznaczne, ale nie udało się skompilować z expected primary-expression before ‘int’. Jeśli skomentuję linię z połączeniem do f, kompiluje się dobrze.Dlaczego pojawia się błąd podczas próby wywołania funkcji elementu szablonu z jawnym parametrem typu?

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

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

Pochwalam Cię za nie tylko odnalezienie tego bezbożnego problemu, ale za to, że nigdy go nie przysięgałeś podczas jego opisywania. –

Odpowiedz

129

Wynika to naprawdę niejasne postanowienia standardu, w którym, jeśli masz szablon, który próbuje uzyskać dostęp do funkcji szablonu w obiekcie, którego rodzaj zależy od szablonu argumentu, trzeba użyć słowa kluczowego template w dziwny sposób:

this->template f<int>(); 

ta jest podobna do tajemniczości z typename że wyjdzie z typów zależnych, o ile zastosowane do funkcji. W szczególności, jeśli pominąć słowa kluczowego template, tam parsowania dwuznaczność pomiędzy

this->f<int>() 

(czego nie przeznaczonych), a

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

który nie ma sensu (stąd swój błąd). Użycie słowa kluczowego template ujednolica i zmusza kompilator do rozpoznania, że ​​patrzy on na całkowicie poprawne wywołanie funkcji szablonu, a nie na zniekształconą masę symboli.

Mam nadzieję, że to pomoże!

+2

Znałem już kilka dziwactw składniowych przy szablonach, ale nigdy wcześniej nie słyszałem tego. – Gorpik

+0

@Gorpik: dlatego powinieneś unikać takich rzeczy :) – akira

+1

@templatetypedef: czy wiesz, że jakiś kompilator prawidłowo to diagnozuje? Byłoby interesujące zobaczyć, czy CLang (który twierdzi przyjazną diagnozę) sugerowałby wstawienie 'szablonu' jako wskazówki dotyczącej poprawki, niestety nie jest to przydatne. –