2015-04-03 18 views
5

Tôi cần khai báo một lớp có thể lưu trữ các loại vùng chứa khác nhau. tức là nó sẽ tốt đẹp nếu nó có thể xử lý std :: bitset và std :: array. Tuy nhiên, hai lớp này cần một đối số mẫu khác nhau ... Có thể (và có thể, cách) sử dụng các lớp mẫu templated và các mẫu variadic để khai báo loại lớp này?Khai báo đối tượng "vùng chứa" từ lớp mẫu templated và các mẫu variadic

Ví dụ (nhưng sai):

template<template <typename..., std::size_t> class Container, 
     std::size_t N, 
     typename... Args> 
class Base_Class 
{ 
    ... 
    Container<Args..., N/2> container; 
}; 

Trình biên dịch phàn nàn rằng N/2 không phải là một loại. Rõ ràng, cho cả hai std :: mảng và std :: bitset tôi cần kích thước để được tham số mẫu cuối cùng ... Có thể mã này điên rồ?

Cảm ơn bạn!

EDIT: Theo như tôi lo ngại, vấn đề chính là các mẫu variadic chỉ có thể được mở rộng ở bên phải, do đó tham số variadic phải là cuối cùng. Bất cứ ai biết nếu có bất kỳ kế hoạch để cho phép cú pháp sau trong C + + 17?

template<typename... Args, typename T> 
struct A 
{}; 
+0

mà trình biên dịch ? – Walter

+0

Nó cho lỗi với cả g ++ và clang (rõ ràng với tham số -std = C++ 11/14) – dodomorandi

Trả lời

3

câu trả lời Anton có thể được thực hiện hơi ít container cụ thể bằng cách sử dụng thông số template mẫu cho các speciliasations của ResizedContainer:

namespace detail { 
    template<typename Container> 
    struct ResizedContainer; 

    template<template<typename,std::size_t> class Container, 
      typename T, std::size_t N> 
    struct ResizedContainer<Container<T,N>> { 
     using type = Container<T,N/2>; 
    }; 

    template<template<std::size_t> class Container, 
      std::size_t N> 
    struct ResizedContainer<Container<N>> { 
     using type = Container<N/2>; 
    }; 
} 

#include <array> 
#include <bitset> 

template<typename Container> 
class Base_Class { 
    typename detail::ResizedContainer<Container>::type container; 
}; 

int main() { 
    Base_Class<std::array<int,4>> a; 
    Base_Class<std::bitset<5>> b; 
} 
2

Có lẽ một cái gì đó như thế này:

namespace detail { 
    template<typename Container> 
    struct ResizedContainer; 

    template<typename T, size_t N> 
    struct ResizedContainer<std::array<T, N>> { 
     using type = std::array<T, N/2>; 
    }; 

    template<size_t N> 
    struct ResizedContainer<std::bitset<N>> { 
     using type = std::bitset<N/2>; 
    }; 
} 

template<typename Container> 
class Base_Class { 
    typename detail::ResizedContainer<Container>::type container; 
}; 

int main() { 
    Base_Class<std::array<int, 4>> a; 
    Base_Class<std::bitset<5>> b; 
} 
+0

Điều này khá tốt. Dù sao, nó là khá cụ thể container. Bất kỳ ý tưởng nào để tránh chuyên môn hóa mẫu và viết ra một lớp mẫu chung hoàn chỉnh? – dodomorandi

+1

@dodomorandi Tôi nghĩ bạn không thể. Cú pháp C++ không cho phép nó. –

+0

@AntonSavin * Cú pháp C++ không cho phép nó. * Tôi nghi ngờ bạn đúng, nhưng bạn có thể 'chứng minh' điều đó không? – Walter

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