2012-01-24 21 views
10

Oto kod testuSłowo kluczowe "szablon" nie jest potrzebne? [Gcc/dzyń/Comeau bug?]

template <class T> void f() 
{ 
    T t; 
    t.f<T>(0); //compiles even without the "template" keyword, what am I missing? 
} 

class abc 
{ 
    public: 
    template <typename T> 
    void f (int){} 
}; 

int main() 
{ 
    f<abc>(); 
} 

używam g ++ 4.4.6. Dzięki

P.S: Znacznie zredagowałem moje pytanie. Proszę, nie przejmuj się.

EDIT: Poprosiłem to pytanie do EDG ludzi i to właśnie Mike Herrick miał powiedzieć

Mamy zdiagnozować to jako błąd w trybie --strict jak również dowolny tryb, który umożliwia zależne wyszukiwanie nazwy (np. --dep_name, --parse_templates). Wyszukiwanie nazw zależnych jest wyłączone w trybach emulacji GNU, więc nie wysyłamy tego błędu w takim przypadku.

Przetwarzanie nazwy zależnej wymaga, aby włączone były prototypowe instancje nieklasy (patrz poniżej). Podobnie jak w przypadku prototypowych instancji typu "nonclass", włączenie wyszukiwania zależnej nazwy prawdopodobnie spowoduje błędy kompilacji podczas kompilowania kodu , który nie został napisany z myślą o tej funkcji.

Zależne reguły wyszukiwania nazw wymagają, aby niezależne nazwy były sprawdzane w punkcie użycia w definicji szablonu, i aby w przypadku tego połączenia przeprowadzać niezależne wywołania w celu sprawdzenia przeciążenia . W przypadku wywołań zależnych zestaw nazw jest zestawem widocznym w miejscu użycia w definicji szablonu oraz wszystkich nazw utworzonych widocznych przez wyszukiwanie zależne od argumentu w punkcie tworzenia instancji. Należy pamiętać, że typy wbudowane nie mają przypisanych obszarów nazw, dlatego wywołania z tylko wbudowanymi typami mogą dotyczyć tylko nazw widocznych w definicji szablonu . Ponadto nazwy z zależnych klas bazowych nie są widoczne dla niewykwalifikowanych wyszukiwań.

Poniżej przedstawiono niektóre z najczęstszych problemów napotykanych kodu przy użyciu nazwy zależną odnośnika:

template <class T> struct B { 
    void f(); 
    }; 

template <class T> struct A : public B<T> { 
    X x; // error: X not visible yet (formerly an error in strict mode) 
    void g() { 
     f();  // error: B<T>::f not visible 
     this->f(); // must be written this way 
     h(1); // error: h(int) not visible using argument-dependent lookup 
    } 
    }; 
struct X {}; 
void h(int); 
A<int> ai; 
+2

Jeśli zmienisz nazwę elementu 'f', więc nie będzie on udostępniać nazwy globalnego' f', to nie skompiluje się na GCC bez określenia 'szablonu'. Nie wiem, dlaczego to robi różnicę. – interjay

+0

Gcc stał się mądrzejszy. :) – iammilind

Odpowiedz

8

template kluczowe jest konieczne zarówno ze względu t to nazwa zależne i dlatego f<T> jest zależny funkcja członek szablonu specjalizacji. Odpowiednia specyfikacja jest rozproszona w punkcie 14, ale zaczyna się od § 14.2/4 (w C++ 03 i C++ 11).

Problem jest spowodowany nieprawidłową nazwą odnośnika: gcc jest znalezienie przestrzeni nazw zakres funkcji szablonu f w momencie zgłoszenia, a następnie w momencie konkretyzacji postanawia f do szablonu funkcję składową abc.

Jeśli zmienisz nazwę szablonu funkcji obszaru nazw lub szablonu funkcji członka, otrzymasz poprawne zachowanie z kompilatora.

Jest to dawna gcc bug:

Code with missing "template" keyword wrongly accepted

Weird clash with same names in different scopes

Zobacz również wiele zduplikowanych rozwiązany błędy przeciwko obu z nich. Nie widzę do tego błędu Clang.

Wyszukiwanie nazw z poziomu szablonu funkcji zostało niedookreślone w C++ 03; zgłoszono wiele błędów na ten temat, a specyfikacja uległa poważnym zmianom w C++ 11 w celu wyjaśnienia szczegółów i przypadków narożnych oraz naprawienia subtelnych problemów.

+0

Nawet Comeau nie daje żadnego błędu. Uważam, że jest to najbardziej standardowy zgodny kompilator, jaki mamy dzisiaj. –

+0

Dzięki za odpowiedź BTW. –

+0

Ok Zamierzam zgłosić ten błąd do EDG. :-) –

2

mogę się mylić, ale myślę, że jest to błąd w GCC. Rozważmy następujący przypadek:

template <class T> bool f() {T t = {2}; return t.f < 4;} 

struct abc { int f; }; 

int main() { f<abc>(); } 

Spodziewam się, że do opracowania dobrze, ale GCC (i Clang) Zakładamy, że t.f nazwy funkcji szablonu i oczekujemy zamknięcia >. Odpowiednią częścią normy jest §14.2/4.

To powiedziawszy, jestem nieco niezdecydowany, twierdząc, że taki błąd może istnieć zarówno w Clang, jak iw GCC bez dodatkowych dowodów. Wrócę po bardziej standardowym nurkowaniu.

+0

Mój kod został skompilowany także na Comeau online. –

+0

Hmmm, byłbym zainteresowany prawdziwą odpowiedzią na to pytanie. Zachowanie wszystkich kompilatorów, których próbowałem, jest sprzeczne z moim zrozumieniem standardu, więc mógłbym wiele się nauczyć. – Mankarse

+1

Jeśli zmieniam nazwę elementu 'f', aby nie współużytkować nazwy funkcji szablonu, kompiluje się to pomyślnie na GCC. Zobacz także mój komentarz do pytania. – interjay

Powiązane problemy