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

C++20标准中为何会忽略函数的void形参?

问题背景与疑问

我正在开发一个框架,允许用户注册函数并由框架代为调用。该框架仅接受至少包含一个形参的函数,以此减少副作用过多的函数。我通过编译期检查函数的输入参数数量实现了这一限制,代码如下:

template <typename R, typename... Args>
constexpr std::size_t number_input_parameters(R (*)(Args...)) { return sizeof...(Args); }

使用示例:

int no_parameters() {} // 会被框架拒绝
static_assert(number_input_parameters(no_parameters) == 0);

开发时我担心形如int still_no_parameters(void) {}的函数——这类函数看起来声明了一个void形参,但按需求也应该被框架拒绝。实际测试后发现,上述实现给出了正确结果(在Clang 15和GCC 12中):

static_assert(number_input_parameters(still_no_parameters) == 0);

显然编译器将R(void)类型的函数解析为了R()类型,想了解在C++20标准中,是如何规定要忽略函数的void形参的?

C++20标准中的相关规定

在C++20标准的【dcl.fct】条款中明确了这一行为:

由单个未命名的void类型参数构成的参数列表,等价于空参数列表。除了这个特殊情况外,参数不能是cv限定的void类型。

这一规定是为了兼容C语言的写法:在C语言中,f(void)明确表示函数不接受任何参数,而f()表示参数数量和类型未指定;但在C++中,f()本身就表示无参数函数,同时保留了f(void)作为等价写法,以此兼容C代码的习惯。

对应到场景中,int still_no_parameters(void)的函数类型会被编译器视为int(),因此模板推导时Args...会被推导为空参数包,sizeof...(Args)的结果为0,符合对无参数函数的判断逻辑,从而正确拒绝这类函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:50:42