在可变参数模板参数中混合类型和非类型?

时间:2017-02-08 23:44:34

标签: c++ variadic-templates

是否可以在可变参数模板参数中混合类型和非类型?如果我将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;
                               ^

有没有办法在可变参数上下文中传递类型和值?

2 个答案:

答案 0 :(得分:5)

  

是否可以在可变参数模板参数中混合类型和非类型?

没有。你不能混合搭配。但是既然你可以将一个值包装在一个类型中而不是相反的方式,那么你可以保持在类型的世界中:

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;

答案 1 :(得分:2)

正如我所看到的,你可以将类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!
}

如果您想使用可变参数模板,那么也将它放在模板模板参数中:

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>;