如何实现对元素相加结果不可默认构造的两个std::array求和?
非默认构造类型的std::array求和实现方案
问题描述
常规的std::array求和函数在处理非默认构造类型时会失效,因为原实现依赖默认构造std::array后逐个赋值,而非默认构造类型无法完成默认初始化:
template<class T, std::size_t N> auto sum(const std::array<T, N>& a, const std::array<T, N>& b) { std::array< decltype(a[0] + b[0]), N> result; // 非默认构造类型无法默认初始化 for (std::size_t i = 0; i < N; ++i) { result[i] = a[i] + b[i]; } return result; }
需求要点:
- 直接构造并初始化目标
std::array,规避默认构造步骤 - 仅依赖C++标准库,不使用
std::vector(避免不必要的拷贝开销) - 希望利用
std::index_sequence解决递归模板无法完成的问题
解决方案:编译期索引序列初始化
利用std::index_sequence生成编译期索引,通过辅助函数直接展开初始化列表构造std::array,完全绕开默认构造环节。
完整实现
#include <array> #include <utility> // 辅助函数:接收编译期索引序列,展开每个位置的求和操作 template<class T, std::size_t N, std::size_t... Is> auto sum_impl(const std::array<T, N>& a, const std::array<T, N>& b, std::index_sequence<Is...>) { using ResultType = decltype(a[0] + b[0]); return std::array<ResultType, N>{a[Is] + b[Is]...}; } // 对外接口:生成对应长度的索引序列并转发给辅助函数 template<class T, std::size_t N> auto sum(const std::array<T, N>& a, const std::array<T, N>& b) { return sum_impl(a, b, std::make_index_sequence<N>{}); }
工作原理
std::make_index_sequence<N>会生成包含0, 1, ..., N-1的编译期索引序列,类型为std::index_sequence<0, 1, ..., N-1>- 辅助函数
sum_impl通过参数包展开Is...,将每个索引对应的a[Is] + b[Is]作为std::array的初始化元素 - 这种方式直接通过初始化列表构造
std::array,不需要默认构造元素,完美适配非默认构造的结果类型
可选扩展:重载operator+
如果需要用+运算符直接对两个std::array求和,可补充以下实现:
template<class T, std::size_t N> auto operator+(const std::array<T, N>& a, const std::array<T, N>& b) { return sum(a, b); }
内容的提问来源于stack exchange,提问作者alxbilger
相关产品推荐
相关产品推荐

