如何用折叠表达式创建N个float元素的数组?现有函数能否改写?
使用折叠表达式创建N个float元素的数组及改写make_ones函数
要使用折叠表达式处理固定大小N的数组,核心是构造一个长度为N的参数包——因为折叠表达式必须基于参数包展开。通常我们借助std::index_sequence(C++14引入)来生成对应长度的索引序列,以此作为可展开的参数包。
一、用折叠表达式创建N个float元素的数组
以创建全1数组为例,我们可以通过辅助模板函数结合索引序列实现:
#include <array> #include <utility> // 用于std::index_sequence和std::make_index_sequence // 辅助函数:接收索引序列,展开参数包生成全1数组 template<size_t... Is> constexpr std::array<float, sizeof...(Is)> make_ones_impl(std::index_sequence<Is...>) { // 折叠表达式:利用逗号表达式忽略索引值,每个位置生成1.0f return {{(static_cast<void>(Is), 1.0f)...}}; } // 对外接口:生成长度为N的全1float数组 template<size_t N> constexpr std::array<float, N> make_ones() { // 生成0到N-1的索引序列,传递给辅助函数 return make_ones_impl(std::make_index_sequence<N>{}); }
代码说明:
std::make_index_sequence<N>会生成std::index_sequence<0,1,...,N-1>,其模板参数0,1,...,N-1就是我们需要的参数包Is...。- 折叠表达式
(static_cast<void>(Is), 1.0f)...中,逗号表达式会先执行static_cast<void>(Is)(仅用于占位,避免编译器警告),然后返回1.0f;展开后就会生成N个1.0f,直接初始化std::array。
二、C++20及以上的简化写法(无需辅助函数)
C++20支持模板lambda,可以在函数内直接展开索引序列,省去辅助函数:
#include <array> #include <utility> template<size_t N> constexpr std::array<float, N> make_ones() { std::array<float, N> ret{}; // 模板lambda接收索引序列,用折叠表达式逐个赋值 [&]<size_t... Is>(std::index_sequence<Is...>) { (ret[Is] = 1.0f, ...); }(std::make_index_sequence<N>{}); return ret; }
这里的折叠表达式(ret[Is] = 1.0f, ...)会依次对每个索引Is执行赋值操作,完成数组初始化。
关键思路总结
- 折叠表达式必须依赖参数包,因此当只有模板参数
N时,需要通过std::index_sequence将N转换为长度为N的参数包。 - 无论是初始化数组还是赋值,核心都是利用索引序列生成的参数包,通过折叠表达式完成批量操作。
内容的提问来源于stack exchange,提问作者user877329
相关产品推荐
相关产品推荐

