2017-02-08 6 views
7

Можно ли смешивать типы и нетипы в параметрах вариационной матрицы? Если бы я передал std::array, например, этому классу в качестве параметра T, мне также нужно было бы передать тип для массива и длину, но способ, которым я попробовал это ниже, вызывает ошибку при достижении значения, поскольку он только ожидает типы для Types:Типы смешивания и нетипы в вариационных параметрах шаблона?

template < 
    template<class, std::size_t> class T, 
    class ... Types> 
class C { 

    T<Types...> storage; 
}; 

int main(){ 
    C<std::array, int, 3> c; 
} 

сообщение об ошибке:

error: template argument for template type parameter must be a 
     type 
    Container<std::array, int, 3> c; 
          ^

есть ли способ передать типы и значения в VARIADIC контексте?

ответ

2

Как я вижу, вы alreadty жестко закодировали число и типы параметров, которые должен принимать класс T в качестве параметра шаблона. Здесь вам не нужны вариативные шаблоны. Просто сделайте это вместо:

template < 
    template<class, std::size_t> class T, 
    class A, std::size_t N> 
class C { 

    T<A, N> storage; 
}; 

int main(){ 
    C<std::array, int, 3> c; // works! 
} 

Если вы хотите использовать VARIADIC шаблоны, а затем положить его в параметре шаблона шаблон также:

template < 
    template<typename...> class T, 
    typename... Types> 
class C { 

    T<Types...> storage; 
}; 

Если вы хотите использовать эту версию, но все еще хотите использовать std::array , вы можете создать псевдоним для std::array, который уже имеет размер:

template<typename T> 
using array3 = std::array<T, 3>; 

C<array3, int> c; 

в качестве альтернативы, вы можете также создать своего рода шаблон шаблон псевдонима, пусть у НУ выбрать размер:

template<std::size_t n> 
struct sized_array { 
    template<typename T> 
    using array = std::array<T, n>; 
}; 

C<sized_array<5>::array, int>; 
4

Можно ли сделать смешивание типов и nontypes в параметрах шаблона переменного числа?

Нет. Вы не можете смешивать и сопоставлять. Но так как вы можете обернуть значение типа, но не наоборот, вы можете просто остаться в мире типов:

template <template<class...> class T, class ... Types> 
class C {  
    T<Types...> storage; 
}; 

А потом это просто вопрос создания std::array работы только с типами:

template <class T, class N> 
using my_array = std::array<T, N::value>; 

template <size_t N> 
using size_ = std::integral_constant<size_t, N>; 

Так что ваш оригинальный пример становится:

C<my_array, int, size_<3>> c;