首页 > 解决方案 > 是否可以在另一个模板参数的模板参数中声明模板参数?

问题描述

我正在尝试创建一个以 astd::array作为模板参数的类模板。目前,声明如下:

template<typename T, std::size_t N, std::array<std::size_t, N> A>
class Foo {
    ...
}

然而,这是非常不幸的,因为我通常会A使用初始化列表进行初始化,这使得指定N繁琐和多余的需要:

// Current
Foo<int, 3, {5, 3, 4}> bar;

// Preferred
Foo<int, {5, 3, 4}> baz;

我尝试使用类似于模板模板参数的东西无济于事:

template<typename T, template<std::size_t N> std::array<std::size_t, N> A>

有没有办法完成我想要做的事情,或者N通过将它A放在参数列表中来“隐藏”?

标签: c++arraystemplatesc++20

解决方案


可以选择添加包装器,因此以下代码将起作用:

Foo2<as_std_array<5, 3, 4>> baz2;

as_std_array定义为:

template<auto item, auto... items>
struct as_std_array {
    using TYPE = std::common_type_t<decltype(item), decltype(items)...>;
    constexpr static std::size_t SIZE = sizeof...(items)+1;
    constexpr static auto ARRAY = std::array<TYPE, SIZE>{item, items...};
};

FooFoo2为:

template<std::size_t N, typename T, std::array<T, N> A>
struct Foo {
    constexpr static auto ARRAY = A;
};

template<typename T>
class Foo2: public Foo<T::SIZE, typename T::TYPE, T::ARRAY>{};

然后以下工作:

Foo2<as_std_array<5, 3, 4>> baz2;    
static_assert(baz2.ARRAY == std::array{5, 3, 4});

链接到代码


推荐阅读