如何编写支持非默认构造类型的std::array拼接函数?
修复非默认构造类型下的std::array拼接函数
原代码的核心问题在于:std::array<T, sza+szb> result;会触发std::array的默认构造,而std::array的默认构造会尝试默认构造内部的每一个元素。当T是非默认构造类型(无公开无参构造函数)时,这一步会直接编译失败。
修复方案
利用C++17引入的std::index_sequence和聚合初始化特性,直接从输入数组的元素拷贝构造结果数组,完全跳过默认构造步骤:
#include <array> #include <utility> template <typename T, std::size_t sza, std::size_t szb, std::size_t... Is, std::size_t... Js> std::array<T, sza + szb> concat_impl(const std::array<T, sza>& aa, const std::array<T, szb>& ab, std::index_sequence<Is...>, std::index_sequence<Js...>) { // 聚合初始化:直接用两个数组的元素拷贝构造结果数组的每个元素 return {aa[Is]..., ab[Js]...}; } template <typename T, std::size_t sza, std::size_t szb> std::array<T, sza + szb> concat(const std::array<T, sza>& aa, const std::array<T, szb>& ab) { // 生成对应长度的索引序列,传递给实现函数 return concat_impl(aa, ab, std::make_index_sequence<sza>{}, std::make_index_sequence<szb>{}); }
方案说明
- 索引序列展开:
std::make_index_sequence<N>会生成一个包含0到N-1的索引序列模板参数,concat_impl通过参数包展开Is...和Js...,遍历两个输入数组的所有元素。 - 聚合初始化:结果数组通过
{aa[Is]..., ab[Js]...}的方式完成聚合初始化,每个元素都直接从输入数组拷贝构造,无需默认构造后再赋值,完美适配非默认构造类型。 - 效率优化:相比原代码的"默认构造+赋值"两步操作,该方案直接一步完成构造,避免了冗余操作,性能更优。
内容的提问来源于stack exchange,提问作者n.m.is-an-unemployed-ai-agent
相关产品推荐
相关产品推荐

