2013-03-19 9 views
14

Kod:Nieuwarunkowany dostęp do członka wyników zależy od klasy bazowej w "A zgłoszenia [x] muszą być dostępne"

// test3.cpp 

#include <stack> 

using namespace std; 

template<typename T> 
struct ptr_stack_tp; 

template<typename T> 
struct ptr_stack_tp<T*> : public stack<T*> 
{ 
    ~ptr_stack_tp() 
    { 
     while (!empty()) { 
      operator delete(top()); 
      pop(); 
     } 
    } 
}; 

int main() 
{} 

komunikat błędu (GCC 4.7.2)

test3.cpp: In destructor 'ptr_stack_tp<T*>::~ptr_stack_tp()': 
test3.cpp:15:23: error: there are no arguments to 'empty' that depend on a template parameter, so a declaration of 'empty' must be available [-fpermissive] 
test3.cpp:15:23: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated) 
test3.cpp:16:33: error: there are no arguments to 'top' that depend on a template parameter, so a declaration of 'top' must be available [-fpermissive] 
test3.cpp:17:17: error: there are no arguments to 'pop' that depend on a template parameter, so a declaration of 'pop' must be available [-fpermissive] 

funkcje empty(), top() i pop() są funkcjami std::stack, więc dlaczego gcc ich nie znajduje?

+3

To nazwa zależna, 'this-> empty()' etc. – Xeo

+3

Ten kod jest ryzykowny. Jeśli pominiesz 'ptr_stack_tp' jako wskaźnik do' stosu 'i wywołasz' delete', otrzymasz (prawdopodobnie) ogromny wyciek pamięci, który jest bardzo trudny do znalezienia. Nie wyprowadzaj ze standardowych klas bibliotek, zamiast tego implementuj ich zachowanie według kompozycji. – filmor

Odpowiedz

27

Powinieneś jawnie wywołać funkcje składowe klasy podstawowej w szablonie klasy za pomocą wskaźnika this.

// ... 

template<typename T> 
struct ptr_stack_tp<T*> : public stack<T*> 
{ 
    ~ptr_stack_tp() 
    { 
     while (!this->empty()) { 
     //  ^^^^^^ 
      operator delete(this->top()); 
      //    ^^^^^^ 
      this->pop(); 
     // ^^^^^^ 
     } 
    } 
}; 

// ... 

Wynika to ze sposobu, w jaki dwufazowe wyszukiwanie nazw działa dla szablonów. Bez indirect this->, kompilator będzie wyglądał spróbować rozwiązać niewykwalifikowanych nazw jako nazwy funkcji globalnych. Ponieważ nie istnieją żadne funkcje globalne o nazwie empty(), top() i pop(), kompilator wyśle ​​błąd.

Kiedy używasz this->, kompilator opóźni wyszukiwanie nazwy do momentu, w którym szablon jest faktycznie utworzony: w tym momencie funkcja wywoływania do członków klasy bazowej zostanie poprawnie rozwiązana.

+0

Rzeczywiście całkiem proste. Dzięki. –

+0

Aby uzyskać więcej informacji, zobacz również [tutaj] (http://stackoverflow.com/questions/5286922/g-template-parameter-error) (twoje pytanie jest duplikatem). –

+0

@ Peregring-lk: Nie ma za co. Czy ta odpowiedź rozwiązuje Twój problem? –