2010-03-17 36 views
11

Đây là kịch bản: Tôi muốn có một lớp máy chủ có thể có một số biến của mixin (không quá khó với các mẫu variadic - xem ví dụ http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.144). Tuy nhiên, tôi cũng muốn các mixin được tham số hóa bởi lớp máy chủ, để chúng có thể tham chiếu đến các kiểu công khai của nó (sử dụng thành ngữ CRTP). Sự cố phát sinh khi cố gắng kết hợp hai - cú pháp chính xác không rõ ràng với tôi. Ví dụ, đoạn mã sau thất bại trong việc biên dịch với g ++ 4.4.1:Mixins, variadic mẫu, và CRTP trong C++

template <template<class> class... Mixins> 
class Host : public Mixins<Host<Mixins>>... { 
    public: 
    template <class... Args> 
    Host(Args&&... args) : Mixins<Host>(std::forward<Args>(args))... {} 
}; 

template <class Host> struct Mix1 {}; 

template <class Host> struct Mix2 {}; 

typedef Host<Mix1, Mix2> TopHost; 
TopHost *th = new TopHost(Mix1<TopHost>(), Mix2<TopHost>()); 

Với các lỗi:

tst.cpp: In constructor ‘Host<Mixins>::Host(Args&& ...) [with Args = Mix1<Host<Mix1, Mix2> >, Mix2<Host<Mix1, Mix2> >, Mixins = Mix1, Mix2]’: 

tst.cpp:33: instantiated from here 

tst.cpp:18: error: type ‘Mix1<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’ 

tst.cpp:18: error: type ‘Mix2<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’ 

Có ai có kinh nghiệm thành công trộn mẫu variadic với CRTP?

Trả lời

6

Phần sau dường như hoạt động. Tôi đã thêm Mixins... vào các lớp mixin được kế thừa mở rộng gói tham số tại chỗ. Bên ngoài nội dung của mẫu Host, tất cả thông số mẫu của Host phải được chỉ định để Mixins... phục vụ mục đích. Bên trong cơ thể, chỉ cần Host là không đủ để đánh vần tất cả các tham số mẫu của nó. Một loại ngắn tay.

#include <utility> 

template <template<class> class... Mixins> 
class Host : public Mixins<Host<Mixins...>>... 
{ 
    public: 
    Host(Mixins<Host>&&... args) : Mixins<Host>(std::forward<Mixins<Host>>(args))... {} 
}; 

template <class Host> struct Mix1 {}; 
template <class Host> struct Mix2 {}; 

int main (void) 
{ 
    typedef Host<Mix1, Mix2> TopHost; 
    delete new TopHost(Mix1<TopHost>(), Mix2<TopHost>()); 
} 
+0

Tôi đã sửa đổi nó để bao gồm hàm tạo templatized. mẫu Máy chủ lưu trữ (Args && ... args): Mixins (std :: forward > (args)) ... {} – Sumant

+0

Cảm ơn, Sumant. Đề nghị của bạn có ý nghĩa, nhưng không làm việc bằng cách nào đó cho tôi. Bạn đang sử dụng phiên bản trình biên dịch nào? Tôi đã sao chép và dán mã này và khi biên dịch, có: tst2.cpp: Trong hàm 'int main()': tst2.cpp: 16: error: không có hàm nào phù hợp để gọi tới 'Host : : Máy chủ (Mix1 >, Mix2 >) ' tst2.cpp: 7: lưu ý: ứng cử viên là: Máy chủ :: Máy chủ (Mixins > && ...) [với Mixins = Mix1, Mix2] tst2.cpp: 5: lưu ý: Máy chủ :: Máy chủ (const Host &) – Eitan

+0

Ồ, tôi đã bỏ lỡ bản sửa đổi của bạn. Điều này sửa lỗi "không phù hợp với chức năng" lỗi, nhưng phát nổ với "lỗi trình biên dịch nội bộ" :) Vì vậy, một lần nữa, trình biên dịch mà bạn đang sử dụng? – Eitan

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