2010-05-01 30 views
5

Mã sau đây không biên dịch. Tôi nhận được thông báo lỗi: lỗi C2039: 'Asub': không phải là thành viên của 'C'Loại "Được kế thừa" sử dụng CRTP và typedef

Ai đó có thể giúp tôi hiểu điều này không?

Đã thử VS2008 & Trình biên dịch 2010.

template <class T> 
class B 
{ 
    typedef int Asub; 

public: 
void DoSomething(typename T::Asub it) 
{ 

} 
}; 

class C : public B<C> 
{ 
public: 
typedef int Asub; 

}; 

class A 
{ 
public: 
typedef int Asub; 

}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
C theThing; 
theThing.DoSomething(C::Asub()); 

return 0; 
} 
+1

Bạn nên * luôn * p số dòng rovide có lỗi biên dịch. – abelenky

+0

'struct A' trong ví dụ là gì? – AlwaysLearning

Trả lời

7

Bạn đang được một chút công bằng với các trình biên dịch ở đây - C là không đầy đủ mà không B<C> biết đầy đủ và khi xử lý B<C>, C vẫn là một loại không đầy đủ. Có các chủ đề tương tự trên comp.lang.c++.moderatedcomp.lang.c++.

Lưu ý rằng nó hoạt động nếu bạn trì hoãn việc sử dụng bằng cách di chuyển nó thành một định nghĩa hàm thành viên, ví dụ:

struct C : B<C> { 
    void f() { typedef typename C::Asub Asub; } 
}; 

Bạn có thể làm việc xung quanh vấn đề bằng cách hoặc là đi qua các loại một cách rõ ràng lên:

template<class T, class Asub> struct B { /* ... */ }; 
class C : B<C, int> { /* ... */ }; 

... hoặc bằng cách di chuyển chúng đến một số lớp đặc điểm nếu bạn cần vượt qua nhiều hơn:

template<class T, class Traits> struct B { 
    void DoSomething(typename Traits::Asub it) {} 
}; 

struct CTraits { 
    typedef int Asub; 
}; 

struct C : B<C, CTraits> { 
    typedef CTraits::Asub Asub;  
}; 
Các vấn đề liên quan