2013-03-19 19 views
14

Code:truy cập không đủ điều kiện để thành viên của lớp cơ sở kết quả phụ thuộc vào "Tờ khai [x] phải có sẵn"

// 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() 
{} 

Thông báo lỗi (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] 

Chức năng empty(), top()pop() là các chức năng của std::stack, vậy tại sao gcc không tìm thấy chúng?

+3

Đó là tên phụ thuộc, 'this-> empty() 'vv – Xeo

+3

Mã này có rủi ro cao. Nếu bạn truyền xung quanh một 'ptr_stack_tp' như một con trỏ tới' stack 'và gọi' delete' trên đó bạn sẽ nhận được một lỗ hổng bộ nhớ rất lớn (có thể) rất khó tìm. Không lấy được từ các lớp thư viện chuẩn, thay vào đó thực hiện hành vi của chúng theo thành phần. – filmor

Trả lời

27

Bạn nên gọi một cách rõ ràng các hàm thành viên lớp cơ sở trong mẫu lớp thông qua con trỏ this.

// ... 

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

// ... 

Điều này là do cách tra cứu tên hai giai đoạn hoạt động đối với mẫu. Nếu không có sự độc lập this->, trình biên dịch sẽ tìm cách giải quyết tên không đủ điều kiện làm tên của các chức năng toàn cầu. Vì không có hàm toàn cục nào có tên là empty(), top()pop() tồn tại, trình biên dịch sẽ phát ra lỗi.

Khi bạn đang sử dụng this->, trình biên dịch sẽ trì hoãn tra cứu tên vào thời điểm khi mẫu thực sự được khởi tạo: tại thời điểm đó, hàm gọi tới các thành viên của lớp cơ sở sẽ được giải quyết một cách chính xác.

+0

Thực sự đơn giản. Cảm ơn. –

+0

Để biết thêm thông tin, hãy xem [đây] (http://stackoverflow.com/questions/5286922/g-template-parameter-error) (câu hỏi của bạn là một bản sao). –

+0

@ Peregring-lk: Bạn được chào đón. Câu trả lời này có giải quyết được vấn đề của bạn không? –

Các vấn đề liên quan