2012-04-16 36 views
5

a.hTại sao tôi không thể sử dụng biến của lớp cha là lớp mẫu?

template <typename T> 
class A 
{ 
    public: 
    int a; 
} 

b.h

template <typename T> 
class B : public A<T> 
{ 
    public: 
    int f(); 
} 

template <typename T> 
int B<T>::f() 
{ 
    int t; 
    t = this->a; //Okay 
    t = a //Error 
    return 0; 
} 

tại sao lỗi xảy ra khi tôi không sử dụng this->?

Tôi có thể bỏ qua this-> bằng cách sử dụng một số phương pháp không?

(Tôi cố định một số lỗi)

+0

Joachim Pileborg cho bạn câu trả lời. Ngoài ra, mã được cung cấp có các vấn đề khác ngăn không cho nó biên dịch. – Anonymous

+0

Đây có phải là mã thực tế không?Không có dấu chấm phẩy sau khi định nghĩa lớp và toán tử phạm vi cho 'int B : f()' là không chính xác cộng với không dấu chấm phẩy ở dòng lỗi. – hmjd

+0

ồ, đó chỉ là lỗi đánh máy. Tôi sửa nó rồi. –

Trả lời

11

Có hai giai đoạn trong mẫu instantiation ("Hai giai đoạn Tên Lookup").

Trong giai đoạn đầu tiên, tất cả các tên không phụ thuộc đều được giải quyết (tra cứu). Trong giai đoạn thứ hai, các tên phụ thuộc được giải quyết.

Một tên phụ thuộc là một cái tên mà phụ thuộc vào tham số mẫu ví dụ .:

template <typename T> 
void foo() { 
    x = 0; // <- Non-dependent, nothing in that refers to "T". 
       // Thus looked up in phase 1, therefore, an 'x' must be 
       // visible. 

    T::x = 0; // <- Dependent, because it depends on "T". 
       // Looked up in phase 2, which is when it must be visible. 
} 

Bây giờ, bạn viết:

t = this->a; //Okay 
t = a //Error 

Đây là chính xác những gì tôi đã mô tả. Theo thuật ngữ không sao, t được tra cứu trong giai đoạn 2, vì this phụ thuộc vào thông số mẫu.

Cụm từ lỗi được tra cứu trong giai đoạn 1, bởi vì không có gì trong tên đó phụ thuộc vào thông số mẫu. Nhưng trong giai đoạn 1, không thể nhìn thấy a vì trình biên dịch không thể xem xét các mẫu lớp cơ sở trong giai đoạn 1, vì các mẫu có thể chuyên biệt và tại thời điểm khởi tạo, có thể được điều khiển từ mẫu chính, một chuyên ngành khác không có số a, có thể hiển thị.

Ví dụ:

template <typename T> 
    struct Base { 
    }; 


    template <typename T> 
    struct Derived : Base<T> { 
     void foo() { 
      this->a = 0; // As is valid. `this->a` is looked up in phase 2. 
     } 
    }; 


    template <> struct Base<int> { 
     int a;    
    }; 


    int main() 
    { 
      // The following declarations trigger phase 2 lookup. 

      Derived<int> di; // valid, because a later specialized 
           // Base<int> is used and all symbols 
           // are resolved. 

      Derived<float> df; // not valid 
    } 

Btw, tôi đã một lần bằng văn bản this-> is not only a matter of style trong blog của tần số rất thấp của tôi.

+0

Tên phụ thuộc là tên không phụ thuộc vào thông số mẫu -> Tên phụ thuộc là tên phụ thuộc vào thông số mẫu:) – czxyl

+0

@czxyl: Gần nửa thập kỷ để phát hiện ra lỗi này: D Cảm ơn gợi ý:) –

1

B là mẫu và do đó tên của nó không phụ thuộc và do đó phải được tra cứu khi mẫu được xác định, không phải khi mẫu được khởi tạo. Tuy nhiên, tại thời điểm định nghĩa mẫu, các tên phụ thuộc không được biết (có thể có các chuyên ngành của mẫu lớp cơ sở A chưa được nhìn thấy), trình biên dịch không thể giải quyết tên không đủ tiêu chuẩn cho lớp cơ sở. Bạn có thể mang tên vào phạm vi dòng điện qua this-> trình độ chuyên môn, bằng cách đặt trước từ đó A<T>:: hoặc với một tuyên bố using:

template <typename T> 
class B : public A<T> 
{ 
    public: 
    using A<T>::a; 
    int f(); 
}; 

Cũng lưu ý rằng bạn nơi thiếu dấu chấm phẩy sau khi khai báo lớp và dòng được đánh dấu bằng số // Error nhận xét.

+0

"Các tên phụ thuộc không được biết" -> Điều này không có ý nghĩa trong cách nói C++. Tên có thể phụ thuộc hay không, ví dụ: với tên tập tin T, 'A :: x' là một tên phụ thuộc,' x' thì không. Nó có thể có ý nghĩa đối với bạn với tư cách là lập trình viên rằng 'x' là một tên phụ thuộc, nhưng về mặt kỹ thuật,' x' là _not_ một tên phụ thuộc. –

+0

-1: "tên của nó không phụ thuộc và do đó phải được tra cứu" -> Điều này là sai. Có thể có các tên thành viên phụ thuộc. Ví dụ: http://ideone.com/zIa7k –

+0

-1: 'this->' không có gì liên quan đến phạm vi. –

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