2012-04-29 35 views
8

Về CRP nếu tôi muốn thực hiện sự thay đổi nhỏ của nó (sử dụng mẫu tham số mẫu) tôi nhận được một lỗi biên dịch:Tò mò lặp đi lặp lại mẫu - biến thể

template <template <typename T> class Derived> 
class Base 
{ 
public: 
    void CallDerived() 
    { 
     Derived* pT = static_cast<Derived*> (this); 
     pT->Action(); // instantiation invocation error here 
    } 
}; 

template<typename T> 
class Derived: public Base<Derived> 
{ 
public: 
    void Action() 
    { 
    } 
}; 

Tôi không phải là chắc chắn chính xác người ta sẽ chọn hình thức này (điều đó không có biên dịch cho tôi) thay vì sử dụng mặc dù điều này (chỉ hoạt động này)

template <typename Derived> 
class Base 
{ 
public: 
    void CallDerived() 
    { 
     Derived* pT = static_cast<Derived*> (this); 
     pT->Action(); 
    } 
}; 

template<typename T> 
class Derived: public Base<Derived<T>> 
{ 
public: 
    void Action() 
    { 
    } 
}; 

Trả lời

11

Điều này cũng cần phải biên dịch. Chúng ta chỉ cần để có được những mẫu tham số khác được quy định một cách rõ ràng

template <typename T, template <typename T> class Derived> 
class Base 
{ 
public: 
    void CallDerived() 
    { 
     Derived<T>* pT = static_cast<Derived<T>*> (this); 
     pT->Action(); // instantiation invocation error here 
    } 
}; 

template<typename T> 
class Derived: public Base<T,Derived> 
{ 
public: 
    void Action() 
    { 
    } 
}; 
+1

Khá thú vị một trong những đã được rõ ràng về typename T trong tuyên bố hai lần ... Không thực sự hiểu tại sao – Ghita

+1

Chỉ cần nhận ra rằng có nguồn gốc đã truyền nó T tham số cũng có. – Ghita

5

trong ví dụ đầu tiên, lớp mẫu thực sự mất mẫu template tham số, không chỉ mẫu tham số, như bạn đã viết:

template <template <typename T> class Derived> 
class Base 
{ 
    //.. 
}; 

Vì vậy, mã này không có ý nghĩa:

Derived* pT = static_cast<Derived*> (this); 
pT->Action(); // instantiation invocation error here 

đây Derived là một mẫu đối số mẫu mà cần tranh luận mẫu mà bạn đã làm không cung cấp cho nó. Thực tế, trong hàm CallDerived(), bạn không thể biết loại loại bạn cần cung cấp cho nó, để thực hiện những gì bạn định làm.

Cách tiếp cận thứ hai là giải pháp đúng. Sử dụng nó.

+1

Nhưng làm thế nào để cung cấp các mẫu tranh luận trong trường hợp đầu tiên .. Sử dụng có nguồn gốc * pt không hoạt động hoặc – Ghita

+1

@Ghita: 'T' không biết trong lớp cơ sở. Giải pháp khác đã giải thích như thế nào bạn có thể vượt qua 'T' đến cơ sở. Nhưng điều đó là không cần thiết, vì bạn nên đi cho giải pháp thứ hai. – Nawaz

+1

Đôi khi T là cần thiết trong lớp cơ sở. Ví dụ. khi có một thành viên 'T Action();' Chắc chắn, bạn có thể sử dụng một lớp đặc điểm cho T cho mọi lớp Derived, nhưng đôi khi bạn muốn T và Derived thay đổi độc lập. Trong trường hợp đó, bạn muốn tiếp cận [đầu tiên] với mẫu + tham số mẫu-mẫu. – TemplateRex

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