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

为C++概念示例添加std::array支持为何触发编译错误?

问题:std::array版本average函数模板参数推导失败的原因

在学习C++20概念时,基于cppreference的示例实现了针对std::vector的average模板函数,添加std::array的重载版本后,编译出现no matching function for call错误,提示模板参数推导失败,int与long long unsigned int不匹配。

原示例代码

template <typename T> 
requires std::integral<T> || std::floating_point<T>
constexpr double average(std::vector<T> const &vec) {
    const double sum = std::accumulate(vec.begin(), vec.end(), 0.0);        
    return sum / vec.size();
}

int main() 
{
    std::vector sVec { 1, 2, 3, 4, 5};
    assert(average(sVec) == 3); 
}

添加std::array支持后的代码

template <typename T, int size>  // add size
requires std::integral<T> || std::floating_point<T>
constexpr double average(const std::array<T, size> &arr) {  // use std::array<T, size> &arr) instead
    const double sum = std::accumulate(arr.begin(), arr.end(), 0.0);        
    return sum / arr.size();
}

int main() 
{
    std::array sArr { 1, 2, 3, 4, 5};
    assert(average(sArr) == 3);
}

编译错误信息

C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:65:19: 错误:找不到匹配的函数调用‘average(std::array<int, 5>&)’
   65 |     assert(average(sArr) == 3);
      |            ~~~~~~~^~~~~~
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:14:18: 注意:候选函数:‘template<class T>  requires (integral<T>) || (floating_point<T>) constexpr double average(const std::vector<T>&)’
   14 | constexpr double average(const std::vector<T> &vec) {
      |                  ^~~~~~~
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:14:18: 注意:模板参数推导/替换失败:
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:65:19: 注意:‘std::array<int, 5>’并非派生自‘const std::vector<T>’
   65 |     assert(average(sArr) == 3);
      |            ~~~~~~~^~~~~~
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:22:18: 注意:候选函数:‘template<class T, int size>  requires (integral<T>) || (floating_point<T>) constexpr double average(const std::array<T, size>&)’
   22 | constexpr double average(const std::array<T, size> &arr) {
      |                  ^~~~~~~
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:22:18: 注意:模板参数推导/替换失败:
C:\Users\Cheng\OneDrive\Documents\Proj\HackerRank\Cpp\concept_introduction.cpp:65:19: 注意:类型‘int’与‘long long unsigned int’不匹配
   65 |     assert(average(sArr) == 3);
      |            ~~~~~~~^~~~~~

Build finished with error(s).

错误原因

  • std::array的第二个模板参数是无符号整数类型(标准规定为std::size_t,通常对应unsigned long long或同级别无符号类型),但你在重载的模板函数中把第二个参数声明为int(带符号整数)。
  • 当你用类模板实参推导(CTAD)创建std::array sArr {1,2,3,4,5};时,编译器推导得到的类型是std::array<int, 5>,这里的模板参数5是std::size_t类型的字面量。由于带符号整数和无符号整数属于不同类型,模板参数推导无法完成匹配,导致编译错误。

修复方案

将模板参数中的int size替换为std::size_t size(需要包含<cstddef>头文件),或者使用auto size让编译器自动推导参数类型:

方案1:使用std::size_t

#include <cstddef> // 引入std::size_t

template <typename T, std::size_t size>
requires std::integral<T> || std::floating_point<T>
constexpr double average(const std::array<T, size> &arr) {
    const double sum = std::accumulate(arr.begin(), arr.end(), 0.0);        
    return sum / arr.size();
}

方案2:使用auto自动推导

template <typename T, auto size>
requires std::integral<T> || std::floating_point<T>
constexpr double average(const std::array<T, size> &arr) {
    const double sum = std::accumulate(arr.begin(), arr.end(), 0.0);        
    return sum / arr.size();
}

内容的提问来源于stack exchange,提问作者user747562

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:35:11