2009-10-02 39 views
10

Tôi nhớ seing một cái gì đó như thế này đang được thực hiện:Danh sách đối số mẫu có độ dài thay đổi?

template <ListOfTypenames> 
class X : public ListOfTypenames {}; 

có nghĩa là, X thừa hưởng từ một danh sách dài biến của typenames truyền như các đối số mẫu. Mã này là giả thuyết, tất nhiên.

Tôi không thể tìm thấy bất kỳ tham chiếu nào cho điều này. Có thể không? Có phải là C++ 0x không?

Trả lời

23

Bạn có thể làm điều đó trong C++ hiện tại. Bạn cung cấp cho mẫu số tham số "đủ lớn" và bạn cung cấp cho chúng mặc định:

class nothing1 {}; 
class nothing2 {}; 
class nothing3 {}; 

template <class T1 = nothing1, class T2 = nothing2, class T3 = nothing3> 
class X : public T1, public T2, public T3 {}; 

Hoặc bạn có thể tinh vi hơn và sử dụng đệ quy. Trước tiên, bạn hướng tới tương lai tuyên bố mẫu:

class nothing {}; 

template <class T1 = nothing, class T2 = nothing, class T3 = nothing> 
class X; 

Sau đó, bạn chuyên cho trường hợp tất cả các thông số mặc định:

template <> 
class X<nothing, nothing, nothing> {}; 

Sau đó, bạn đúng cách xác định các mẫu chung (mà trước đó bạn đã chỉ về phía trước -declared):

template <class T1, class T2, class T3> 
class X : public T1, public X<T2, T3> 

Lưu ý cách thức trong lớp cơ sở, bạn kế thừa X nhưng bạn bỏ lỡ tham số đầu tiên. Vì vậy, tất cả chúng đều trượt dọc theo một nơi. Cuối cùng tất cả chúng sẽ được mặc định, và chuyên môn sẽ bắt đầu, mà không kế thừa bất cứ điều gì, do đó chấm dứt đệ quy.

Cập nhật: vừa có một cảm giác kỳ lạ Tôi đã đăng tải một cái gì đó như thế này trước đây, and guess what...

+0

bạn cũng có thể sử dụng chỉ là một lớp "không có gì" – sellibitze

+0

@sellibitze - Tôi sử dụng sử dụng chỉ là một "không có gì" lớp trong phiên bản đệ quy. Bạn không thể sử dụng cùng một lớp cho các giá trị mặc định trong phiên bản không đệ quy, vì bạn sẽ nhận được các lỗi "không có gì đã là một lớp cơ sở trực tiếp". –

+0

Tôi không hiểu: tại sao bạn bỏ qua tham số đầu tiên khi kế thừa từ X? – Gili

19

Âm thanh như bạn đang đề cập đến 0x Variadic Templates C++. Bạn cũng có thể đạt được hiệu ứng tương tự bằng cách sử dụng cấu trúc TypeList của Alexandrescu từ Loki.

Tôi tin rằng cú pháp mẫu variadic được đề cập sẽ giống như sau.

template <typename...T> 
class X : public T... {}; 
+13

Nếu tôi không nhầm, bạn cũng cần giải nén loại: 'public T ... {};' – UncleBens

2

Số lượng biến mẫu là một phần của tiêu chuẩn C++ tiếp theo. Tuy nhiên, bạn có thể có được hương vị của nó nếu bạn đang sử dụng GCC (từ phiên bản 4.3). Đây là list of available C++0x features in GCC. Bạn đang tìm Mẫu Biến thể.

Nhân tiện, nếu bạn cần tham chiếu chính thức về cách đạt được cơ chế thừa kế như được mô tả bởi Earwicker, nó nằm trên sách C++ Templates.

4

Khi những người khác đã trả lời, các mẫu variadic là một phần của tiêu chuẩn tiếp theo, nhưng có thể được mô phỏng trong C++ hiện tại. Một công cụ tiện lợi cho việc này là sử dụng thư viện Boost.MPL. Trong mã của bạn, bạn viết một tham số mẫu đơn (hãy đặt tên nó là "Typelist") và người dùng mẫu của bạn bọc trình đánh máy trong một chuỗi MPL. Ví dụ:

#include "YourType.h" 
#include "FooBarAndBaz.h" 
#include <boost/mpl/vector.hpp> 

YourType<boost::mpl::vector<Foo, Bar, Baz> > FooBarBaz; 

Trong khi triển khai "YourType", bạn có thể truy cập các phần tử trong Typelist với nhiều tính năng khác nhau. Ví dụ: at_c<Typelist, N> là phần tử thứ N của danh sách.Một ví dụ khác, lớp "X" trong câu hỏi của bạn có thể được viết với inherit_linearly như:

//Warning: Untested 
namespace bmpl = boost::mpl; 
template<class Typelist> 
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type 
{ 
... 
}; 
Các vấn đề liên quan