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

混合可变参数模板与C风格可变函数的模板实参推导问题

问题解答

结论

GCC 11的输出符合C++标准规范,bar()返回1为正确结果,Clang 13、MSVC 2019的实现不符合标准要求。

标准依据与代码分析

涉及的核心规则来自C++标准[temp.deduct.type]章节的规定:

函数参数包如果出现在函数参数列表的非末尾位置,该参数包对应的模板参数包属于非推导上下文,无法通过函数调用的实参隐式推导得到,只能由用户显式指定。

你的代码中,foo模板的函数参数列表为(Args&& ...args, ...),其中模板参数包Args对应的函数参数包args后跟随了C风格可变参数省略号,不属于参数列表的末尾位置,因此Args属于非推导上下文,不能通过调用实参推导补充模板实参。
当调用foo<int>(1, 2)或者取&foo<int>地址时,仅显式指定了Args的第一个模板实参为int,且Args无法通过后续实参推导增加更多实参,因此Args的最终形态是仅包含一个int的参数包:

  • 第一个调用实参1匹配Args对应的参数包
  • 第二个调用实参2传递给后续的C风格可变参数部分
    最终sizeof...(args)的计算结果为1。
    Clang与MSVC的实现错误地对非推导上下文的参数包执行了实参推导,将两个调用实参都归入Args参数包,得到Args = <int, int>的结果,不符合标准规定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:39:03