C++ 函数到指针的隐式转换:哪个编译器是正确的? Clang 和 GCC 不同意

Posted

技术标签:

【中文标题】C++ 函数到指针的隐式转换:哪个编译器是正确的? Clang 和 GCC 不同意【英文标题】:C++ function-to-pointer implicit conversion: which compiler is right? Clang and GCC disagree 【发布时间】:2019-06-07 17:51:34 【问题描述】:
template <typename Type, Type Func>
struct A

;

void func();

A<void(), func> a; // same result with A<void(), &func> a;

此代码使用 Clang(包括最新的 8.0.0)编译,但不使用 GCC(包括最新的 9.1)。

GCC 说:error: 'void()' is not a valid type for a template non-type parameter

哪个编译器是正确的,为什么?

更新

我猜 GCC 是错误的,因为在 Clang 和 GCC 上都可以编译以下代码:

template <void()>
struct A

;

void func();

A<func> a; // same result with A<&func> a;

因此与 GCC 在第一个示例中的报告相反,void() 似乎是“模板非类型参数的有效类型”

【问题讨论】:

可能相关:A&lt;void(*)(), func&gt; a; 有效 我想不涉及指针(但原始函数类型)并且 GCC 是正确的。这里有关于函数类型与函数指针的某种相关解释:***.com/questions/8573763/… 无论如何,我们需要语言律师来提供具体答案。编辑:A&lt;void(&amp;)(), func&gt; a; 被编译器接受,A&lt;void(&amp;&amp;)(), func&gt; a; 再次被 clang 接受 在更新中非类型模板参数的类型为void(*)(),因为它被调整了。 template&lt;void()&gt; struct A 等价于 template&lt;void(*)()&gt; struct A; demo 【参考方案1】:

与function parameter type的情况类似,如果非类型模板参数的类型是函数类型,则调整为指向函数类型[temp.param]/8的指针:

类型为“T 数组”或函数类型 T 的非类型模板参数被调整为“指向 T 的指针”类型。

所以clang是对的。 GCC 错误报告已经存在bug #82773


只有当前的c++标准工作草案将模板参数substitution的过程识别为以下模板参数。因此可以说该标准并不明确,因为它没有指定在每次替换后执行类型调整。

【讨论】:

Clang 和 GCC 的区别在于它们如何处理第一个模板参数,而不是第二个。 Clang 将第一个模板参数从 void() 转换为 void(*)(),GCC 没有。 @BorisRasin 第一个参数在这两种情况下都是void()。 Clang 对非类型模板参数而不是 GCC 进行调整。我仍在深入研究标准,看看在这种情况下是否也应该进行类型调整,但我怀疑不清楚。 他们都调整第二个参数完全相同。这具有完全相同的结果:A&lt;void(), &amp;func&gt;。区别在于它们如何处理第一个参数。 @BorisRasin 您混淆了术语“参数”和术语“参数”。第一个模板参数是Type,其关联参数是void()。第二个参数是Func,它的关联参数是&amp;func。将第一个参数与其关联的参数替换为第二个参数后,第二个参数的类型为void()。第二个参数 (&amp;func) 的类型是 void(*)() 。 Clang 将第二个参数类型从void() 调整为void(*)()。所以参数&amp;func的类型匹配参数的类型... @BorisRasin ... 对于 GCC,第二个参数类型未调整为 void(*)() 并且非类型模板参数不能具有函数类型,因此 GCC 会报错。

以上是关于C++ 函数到指针的隐式转换:哪个编译器是正确的? Clang 和 GCC 不同意的主要内容,如果未能解决你的问题,请参考以下文章

第五篇:你“ 看不见 ” 的隐式转换

为啥首先允许指针从非常量到常量的隐式转换?

C++,bool 转换是不是总是退回到 void* 的隐式转换?

在构造 std::variant 时禁用从指针类型到 bool 的隐式转换的最佳方法是啥?

C的隐式类型转换

从 int 到向量的隐式转换?