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

lo *_*cre 9 c++ variadic-templates

是否可以在可变参数模板参数中混合类型和非类型?如果我将一个std::arrayfor例作为参数传递给这个类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;
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

error: template argument for template type parameter must be a
      type
    Container<std::array, int, 3> c;
                               ^
Run Code Online (Sandbox Code Playgroud)

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

Bar*_*rry 5

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

不,您不能混搭。但是由于您可以将值包装在类型中,而不能用其他方式包装,所以您可以留在类型的世界中:

template <template<class...> class T, class ... Types>
class C {    
    T<Types...> storage;
};
Run Code Online (Sandbox Code Playgroud)

然后,只需要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>;
Run Code Online (Sandbox Code Playgroud)

因此,您的原始示例变为:

C<my_array, int, size_<3>> c;
Run Code Online (Sandbox Code Playgroud)


Gui*_*cot 3

正如我所看到的,您已经对类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!
}
Run Code Online (Sandbox Code Playgroud)

如果您想使用可变参数模板,请将其也放入模板模板参数中:

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

    T<Types...> storage;
};
Run Code Online (Sandbox Code Playgroud)

如果您希望使用该版本但仍想使用std::array,您可以为std::array已经有大小的版本创建一个别名:

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

C<array3, int> c;
Run Code Online (Sandbox Code Playgroud)

或者,您还可以创建某种模板模板别名,让您选择大小:

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

C<sized_array<5>::array, int>;
Run Code Online (Sandbox Code Playgroud)