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

C++可变参数模板调用无匹配函数及默认参数可行性咨询

问题1:编译错误的原因

是的,报错是可变参数模板的写法不符合C标准规则导致的。
C
对函数参数列表中的可变参数包有明确限制:如果可变参数包没有出现在参数列表的最后一位,编译器无法自动推导参数包的模板类型和长度。
你给出的可变参数重载定义:

template<typename T, typename ... Args>
constexpr size_t get_init_size(T First_arg, Args ... args, size_t i)

其中Args ... args放在了size_t i之前,不属于参数列表末尾元素。当你调用get_init_size(0b01, 0b10, 0b01, static_cast<size_t>(0))传入4个参数时,编译器无法判断Args参数包应该匹配前3个int中的几个(是匹配1个、2个还是0个),模板推导失败,因此找不到匹配的函数。

问题2:添加默认参数后是否可以省略传最后一个参数

不可以。
即使给末尾的size_t i添加默认值,参数包在中间的问题依然存在:调用时传入的所有实参会被优先贪婪匹配给可变参数包,不会自动预留位置给后面带默认值的i,最终依然会因为i没有拿到实参、模板推导失败报错。

正确实现方案

如果你的需求只是获取传入的可变参数数量,C++11及以上版本可以直接用内置的sizeof...运算符,不需要递归实现:

template<typename ... Args>
constexpr size_t get_init_size(Args&& ... args) {
    return sizeof...(Args);
}

// 调用时直接传参数即可,不需要额外传计数初始值
auto create_ipv4_header() {
    size_t x = get_init_size(0b01, 0b10, 0b01);
    return x; // 返回3,符合预期
}

如果必须用递归实现,把计数参数放在参数列表最前面即可:

// 递归终止条件
constexpr size_t get_init_size(size_t i) {
    return i;
}

template<typename T, typename ... Args>
constexpr size_t get_init_size(size_t i, T first, Args ... args) {
    return get_init_size(i + 1, args...);
}

// 调用方式
size_t x = get_init_size(0, 0b01, 0b10, 0b01);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:27:03