当前位置: 首页 > 知识库问答 >
问题:

C语言中具有多个参数包的函数的重载解析

祖新觉
2023-03-14

一个 C 函数可以有多个参数包。虽然它看起来不是很实用,但了解它们的语言规则仍然很有趣。

例如,在两个过载的情况下:

constexpr int f(auto...) { return 1; }
constexpr int f(auto..., auto...) { return 2; }

带参数 f() 的 f 在 MSVC 中选择版本 1,在 Clang 中选择版本 2,在 GCC 中选择不明确的重载调用

如果使用参数f(1)调用f,则MSVC和GCC都选择版本1,而Clang仍然选择版本2。

演示:https://gcc.godbolt.org/z/PWr6h1dn1

哪个编译器就在这里?

有一个类似的问题函数模板重载解析两个参数包,但是

    < li >那里的函数只有一个参数包作为函数参数(第二个参数包根本没有使用), < li >此处的示例在所有测试的编译器中都导致了歧义错误(但是提到的编译器错误仍未解决)。实际上,在这个例子中,歧义也是可以预期的,但是这里大多数编译器选择了一个重载而没有错误。

共有1个答案

严天逸
2023-03-14

在这两种情况下,这将导致程序因不明确而被拒绝。

首先请注意:

在函数调用的上下文中,使用的类型是函数调用具有参数的函数参数类型。

也就是说,只有提供的实际参数才有助于函数模板部分排序。因此,(2)中前面函数参数包的存在不会导致一个函数模板对另一个函数模板的推导过程;它被推断为空并且没有进一步的贡献。

现在,使用尾随包进行部分排序的决胜局无济于事,因为两者都有一个尾随包:

[...]如果G有一个F没有对应参数的尾随函数参数包,并且如果F没有尾随函数参数包,那么FG更专业。

但两者都有一个尾随参数包,并且长度相同,因此“whichF上的语言没有相应的参数”(这一点不完全清楚;请参见CWG 1395)也没有帮助。

我认为,如果提供了模板参数(并且它们是可以推断的参数),那么(2)应该是首选的,因为在这种情况下,它的尾随函数参数包将更短。但是,这一点非常不清楚。clang同意我的观点,但gcc和MSVC采取了相反的路线。

 类似资料:
  • 作为 C 语言程序的入口 mian 函数很多时候会在启动的时候从外界传入一些参数到程序内部。 1. main 函数的参数 其实从函数角度的讲, mian 函数和其它函数没有什么特别之处。只不过这个函数是又操作系统直接引导的,在大多数的情况下是程序的入口。因此而显得特殊。 之前我们介绍的程序中都是没有参数的 mian 函数,这里我们看一下一般情况下 mian 函数的参数情况。 int main(in

  • 主要内容:形参和实参的区别和联系如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。 这一节我们先来讲解C语言函数的参数,下一节再讲解C语言函数的返回值。 C语言函数的参数会出现在两个地方,分别是函数定义处和函数调用处,这两个地方的参数是有区别的。 形参(形式参数) 在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来

  • 考虑以下层次结构: 访客类: 通常,当重载方法依赖于参数类型时,我使用访问者模式来实现双重调度,但我只有指向基类的指针。 例如: 我认为这是实现双重调度的唯一方法,因为虚拟函数的动态绑定应该只发生在调用方法的对象上,而不是其参数(派生类型)上。 现在我遇到了一个新情况,我需要一种在多个参数上重载的Visit方法。类似于这样: 我不能使用经典的访问者模式解决方案,因为接受方法只对其中一个参数调用。

  • 问题内容: 我正在将C库移植到Go。AC函数(带有varargs)的定义如下: 因此,我创建了包装器C函数: 如果我在Go中定义函数是这样的: Go编译器抱怨: 那么Go支持功能(方法)重载了吗,还是这个错误意味着其他? 问题答案: 不,不是的。 请参阅Go语言常见问题解答,尤其是有关重载的部分。 如果方法调度也不需要进行类型匹配,则可以简化该方法。其他语言的经验告诉我们,使用具有相同名称但签名不

  • 本文向大家介绍详解C语言中的getgrgid()函数和getgrnam()函数,包括了详解C语言中的getgrgid()函数和getgrnam()函数的使用技巧和注意事项,需要的朋友参考一下 C语言getgrgid()函数:从组文件中取得指定gid的数据 头文件: 定义函数: 函数说明:getgrgid()用来依参数gid 指定的组识别码逐一搜索组文件, 找到时便将该组的数据以group 结构返回