You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现对元素相加结果不可默认构造的两个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>{});
}

工作原理

  1. std::make_index_sequence<N>会生成包含0, 1, ..., N-1的编译期索引序列,类型为std::index_sequence<0, 1, ..., N-1>
  2. 辅助函数sum_impl通过参数包展开Is...,将每个索引对应的a[Is] + b[Is]作为std::array的初始化元素
  3. 这种方式直接通过初始化列表构造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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:12:29