C++1y/C++14:将静态 constexpr 数组转换为非类型模板参数包?

问题描述 投票:0回答:2

假设我有一个静态存储持续时间的 constexpr 数组(已知边界):

constexpr T input[] = /* ... */;

我有一个需要包的输出类模板:

template<T...> struct output_template;

我想实例化

output_template
,例如:

using output = output_template<input[0], input[1], ..., input[n-1]>;

执行此操作的一种方法是:

template<size_t n, const T (&a)[n]>
struct make_output_template
{
    template<size_t... i> static constexpr
    output_template<a[i]...> f(std::index_sequence<i...>)
    { return {}; };

    using type = decltype(f(std::make_index_sequence<n>()));
};

using output = make_output_template<std::extent_v<decltype(input)>, input>::type;

我缺少更干净或更简单的解决方案吗?

c++ templates variadic-templates constexpr c++14
2个回答
9
投票

也许你认为这样更干净:

template< const T* a, typename >
struct make_output_template;

template< const T* a, std::size_t... i >
struct make_output_template< a, std::index_sequence< i... > >
{
    using type = output_template< a[ i ]... >;
};

using output = make_output_template<
    input,
    std::make_index_sequence< std::extent_v< decltype( input ) > >
>::type;

0
投票

C++ 17 更新: 使用自动模板参数,我们可以使 OP 的解决方案和 Daniel Frey 的 答案更好用一些。以OP为例:

template<auto& input>
using output = make_output_template<std::extent_v<std::remove_reference_t<decltype(input)>>, input>::type;

可以直接使用,例如:

outupt<input> foo;

请务必使用

auto&
正确捕获数组。使用裸的
auto
它将衰减为常规指针(参见例如 https://stackoverflow.com/a/6443267),
std::extent_v
将为零,但代码仍然可以编译,并且如果您期望可变参数将
output_template
打包为与
input
数组大小相同,你就有了一个全新的 bug。

© www.soinside.com 2019 - 2024. All rights reserved.