2009-10-26 18 views
9

Mam tutaj starą bazę kodów, w której zastosowano chronione zmienne składowe. Można dyskutować, czy jest to dobry pomysł, czy nie. Jednak kod musi być skompilowany dobrze z gcc3. Mam pochodzący klasy szablon bar, który wykorzystuje chroniony członek X z klasy szablonu Foo jak takDostęp do chronionego elementu klasy w klasie pochodnej

template <class Something> class Foo { 
public: 
// stuff... 
protected: 
    some::type x; 
} 

template <class Something> Bar : Foo<Something> { 
public: 
    void cleanup(); 
} 

A w deklaracji metody czyszczenia() jest coś zrobić z X

template <class Something> void Bar<Something>::cleanup() { 
    doSomeThingCleanUpLike (x); 
} 

robi to nie działa z gcc4, chociaż powinno działać z gcc3. Działa, gdy zmieniam go na

doSomeThingCleanUpLike (this->x); 

Dlaczego tak się dzieje?

+1

Termin "klasa szablonów" często jest źródłem nieporozumień. Prawidłowym terminem jest "szablon klasy", ponieważ jest to szablon dla klas. To nie jest klasa. Chciałbym edytować twoje pytanie, ale jest to prawdopodobnie jeden z powodów, dla których się pomyliłeś. – MSalters

+1

Twoja definicja funkcji "porządkowania" nie jest zgodna. pomija typ powrotu i argumenty szablonu dla "Bar". Pewnie, że to jest w twoim kodzie? –

+0

Dzięki litb. Zmieniłem to. poziom kofeiny nie był wystarczająco wysoki, aby go dostrzec. Została również zmieniona na "szablon klasy". Niezależnie od tego, czy szablon szablonu lub szablon klasy nie powinien mieć wpływu na problem. Termin jest po prostu nieformalnie używany. – GeeF

Odpowiedz

13

Wyrażenie x użyte w klasie pochodnej jest, według reguł w standardzie, niezależne od dowolnego parametru szablonu klasy pochodnej. Z tego powodu wyszukiwanie odbywa się w kontekście definicji szablonu, a nie w punkcie użycia/tworzenia instancji. Mimo że szablonowa klasa bazowa szablonu wydaje się być widoczna, ponieważ jest to klasa szablonu, konkretna instancja, która może zostać użyta, może obejmować specjalistyczne szablony, więc definicji szablonu klasy podstawowej nie można użyć do wyszukiwania nazw.

Zmieniając wyrażenie na this->x, tworzysz wyrażenie zależne (this w szablonie klasy zawsze zależy od parametrów szablonu). Oznacza to, że wyszukiwanie wystąpi w kontekście instancji, w którym to momencie klasa podstawowa jest w pełni znana, a jej członkowie są widoczni.

+0

+1 przy użyciu właściwego terminu: * zależne */* inne niż zależne * nazwy. –

6

Podczas definiowania wyprowadzonego szablonu kompilator zna tylko nazwę klasy podstawowej szablonu, ale nie szczegóły, więc kompilator nie wie, że klasa pochodna ma dziedziczony element. Aby powiedzieć kompilatorowi o istnieniu członka, użyj this->, tak jak zrobiłeś.

W rzeczywistości jest to duplikat numeru this question.

+1

Ważne jest, aby pamiętać, że dodanie "this->" nie jest rytuałem, ale sposobem przekształcania niezależnej nazwy w zależną. Zobacz odpowiedź Charlesa. –

+0

Dobry połów, to pytanie ma zły tytuł. Naprawiono teraz. – MSalters

Powiązane problemy