Trong
template <template <class X> class T>
Biến X
không phải là một mẫu tham số cho mẫu ngoài cùng: nó là một mẫu tham số để các mẫu trong cùng. Nó khá giống với
int foo(int (*bar)(int x))
{
int y = x; // compiler error
}
mà không làm việc kể từ khi chức năng phải mất một đối số duy nhất, bar
: không có tranh luận x
.
Tùy thuộc vào những gì bạn thực sự cố gắng để làm, bạn có thể thêm các biến mẫu thứ hai, với một cái gì đó giống như
template <typename X, template <typename> class T >
struct Bar
{
// ...
};
bạn có thể giữ tờ khai với một biến duy nhất, nhưng đối sánh mẫu để cung cấp cho một đặc tả từng phần mà sẽ định nghĩa lớp trong ví dụ bối cảnh
template <typename T>
struct Bar;
template <typename X, template <typename> class T >
struct Bar<T<X>>
{
// ...
};
bạn có thể sửa đổi Foo
để có một loại lồng hữu ích, và lấy nó như vậy
template <typename T>
struct Bar
{
using X = T::value_type;
};
hoặc bạn có thể định nghĩa một metafunction rằng chiết xuất một mẫu tham số từ một kiểu mẫu, và nhận được nó như vậy:
template <typename T>
struct Bar
{
using X = get_parameter<T>;
};
Các linh hoạt nhất là phiên bản cuối cùng, trừ trường hợp chứ không phải là một metafunction rằng chiết xuất mẫu đối số, bạn sẽ khai báo hàm get_bar_parameter
và xác định chuyên môn từng phần trích xuất tham số mẫu từ Foo<X>
(hoặc T<X>
). Bằng cách đó, nếu bạn quyết định sử dụng Bar
trong tương lai với các lớp có giá trị phù hợp của X
không phải là được tính theo cách đó, bạn có thể thực hiện việc này bằng cách cung cấp chuyên môn thích hợp cho get_bar_parameter
.
Ok, có vẻ tốt và biên dịch (Tôi vừa quên cờ -std = C++ 11). Nhưng tôi không hiểu giải pháp của bạn. Tại sao tuyên bố đầu tiên của 'Bar' được yêu cầu? –
@ThomasWitkowski là * mẫu chính *, để tôi có thể chuyên dùng cho trường hợp 'struct Bar> '. nó không được hoàn thành một cách có chủ ý, để nó không được khởi tạo với kiểu khác với một mẫu tham số –