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

为何std::size_t可变参数函数SumIndices编译失败而模板SumValues可正常编译

问题原因分析

你遇到的编译错误本质是因为C++ 不允许非模板函数声明 C++ 风格的参数包,折叠表达式只能作用于模板对应的参数包。C++的参数包分为模板参数包和函数参数包,函数参数包必须绑定到对应的模板参数包才能存在,不存在脱离模板的函数参数包。普通非模板函数如果要写可变参数,只能用C风格的可变参数语法(std::size_t first, ...),这种语法的参数不能用折叠表达式展开,只能通过va_list系列接口操作,使用起来非常繁琐且没有类型安全保障。

两个函数的差异对比

  • SumValues 是模板函数,代码中的 typename ...t_data_type 是模板参数包,对应的函数参数 t_data_type ..._values 会被编译器识别为合法的函数参数包,因此用折叠表达式展开 _values 是符合语法规则的。
  • SumIndices 是普通非模板函数,直接在参数列表写 std::size_t ..._indices 不属于合法的参数包声明语法,编译器不会将 _indices 识别为可展开的参数包,所以你使用折叠表达式展开时就会抛出“expansion pattern contains no parameter packs”的错误。
正确的实现方式

如果你需要实现参数固定为 std::size_t 类型的可变参数求和函数,可以选以下任意一种写法:

写法1:用模板参数包+类型约束(C++20及以上)

#include <concepts>

template <std::same_as<std::size_t> ...t_indices>
constexpr auto SumIndices(t_indices ..._indices) { 
  return (_indices + ...); 
}

或者用更简洁的缩写函数模板写法:

#include <concepts>

constexpr auto SumIndices(std::same_as<std::size_t> auto ..._indices) { 
  return (_indices + ...); 
}

写法2:静态断言校验类型(兼容C++17及以上)

#include <type_traits>

template <typename ...t_indices>
constexpr auto SumIndices(t_indices ..._indices) { 
  static_assert((std::is_same_v<std::size_t, t_indices> && ...), "所有参数必须为std::size_t类型");
  return (_indices + ...); 
}

写法3:非类型模板参数包

如果你的参数都是编译期常量,也可以直接用非类型模板参数包实现:

template <std::size_t ..._indices>
constexpr auto SumIndices() { 
  return (_indices + ...); 
}
// 调用方式:SumIndices<1,2,3>()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:15:09