2010-11-17 30 views
6

Xem xét ++ mã C sau,Thành phần dữ liệu lớp mẫu cơ sở không hiển thị trong lớp mẫu có nguồn gốc?

template <typename Derived> 
struct A 
{ 
    bool usable_; 
}; 

template <typename Derived> 
struct B : A< B<Derived> > 
{ 
    void foo() 
    { 
     usable_ = false; 
    } 
}; 

struct C : B<C> 
{ 
    void foo() 
    { 
     usable_ = true; 
    } 
}; 

int main() 
{ 
    C c; 
} 

tôi đã nhận lỗi biên dịch: Trong chức năng thành viên void B<Derived>::foo():

template_inherit.cpp:12: error: 'usable_' was not declared in this scope.

Tại sao vậy? Bất kỳ sửa chữa tốt?

+0

Trình biên dịch này là gì? –

+3

'struct B: A < B>' wat. – GManNickG

+3

@GMan haha ​​CRTP ngụy trang :) –

Trả lời

13

Đó là vì usable_ là tên không phụ thuộc, vì vậy nó được tra cứu tại thời điểm mẫu được phân tích cú pháp, thay vì được tra cứu lúc khởi tạo (khi lớp cơ sở được biết).

Tra cứu tên không đủ tiêu chuẩn sẽ không tra cứu và tên không phụ thuộc sẽ không bao giờ được tìm kiếm trong các lớp cơ sở phụ thuộc. Bạn có thể làm cho tên usable_ phụ thuộc như sau, mà cũng sẽ thoát khỏi tên không đủ tiêu chuẩn tra cứu

this->usable_ = false; 

// equivalent to: A<B>::usable_ = false; 
A< B<Derived> >::usable_ = false; 

B::usable_ = false; 

Tất cả những sẽ làm việc. Hoặc bạn có thể khai báo tên trong lớp có nguồn gốc với một sử dụng-khai

template <typename Derived> 
struct B : A< B<Derived> > 
{ 
    using A< B<Derived> >::usable_; 

    void foo() 
    { 
     usable_ = false; 
    } 
}; 

Lưu ý rằng trong C sẽ không có vấn đề - nó chỉ ảnh hưởng đến B.

+0

Cuộc họp cuối cùng của GotW về nó. Than ôi, giải pháp thông thường sau đây của Herb Sutter không xảy ra. :( – wilhelmtell

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