C++ C++;函数到指针的隐式转换:哪个编译器是正确的?克朗和海合会不同意 模板 结构A { }; void func(); A;//与A的结果相同;

C++ C++;函数到指针的隐式转换:哪个编译器是正确的?克朗和海合会不同意 模板 结构A { }; void func(); A;//与A的结果相同;,c++,gcc,clang,C++,Gcc,Clang,这段代码使用Clang(包括最新的8.0.0)编译,但不使用GCC(包括最新的9.1) GCC表示:错误:“void()”不是模板非类型参数的有效类型 哪个编译器是正确的,为什么 更新 我猜GCC是错误的,因为以下编译都在Clang和GCC上进行: 模板 结构A { }; void func(); A;//与A的结果相同; 因此,与GCC在第一个示例中报告的情况相反,void()似乎是“模板非类型参数的有效类型”类似于,如果非类型模板参数的类型是函数类型,则将其调整为指向函数类型的指针: 将类

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

GCC表示:
错误:“void()”不是模板非类型参数的有效类型

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

更新 我猜GCC是错误的,因为以下编译都在Clang和GCC上进行:

模板
结构A
{
};
void func();
A;//与A的结果相同;

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

类似于,如果非类型模板参数的类型是函数类型,则将其调整为指向函数类型的指针:

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

所以叮当声是对的。GCC错误报告已存在



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

可能相关:
A工作我假设不涉及指针(但原始函数类型),GCC是正确的。这里有一些关于函数类型和函数指针的相关解释:无论如何,我们需要语言律师来给出具体的答案。编辑:
AA都接受code>在更新中,非类型模板参数的类型为
void(*)(
,因为它已调整<代码>模板结构A
相当于
模板结构AClang和GCC之间的区别在于它们如何处理第一个模板参数,而不是第二个模板参数。Clang将第一个模板参数从
void()。Clang对非类型模板参数进行调整,但不对GCC进行调整。我仍在深入研究标准,看看在这种情况下是否也应该进行类型调整,但我怀疑这并不清楚。它们都调整了完全相同的第二个参数。这有着完全相同的结果:
A
。区别在于它们处理第一个参数的方式。@BorisRasin您混淆了术语“参数”和术语“参数”。第一个模板参数是
Type
,其关联参数是
void()
。第二个参数是
Func
,其关联参数是
&Func
。将第一个参数与其关联的参数替换为第二个参数后,第二个参数的类型为
void()
。第二个参数(
&func
)的类型是
void(*)(
)。将第二个参数类型从
void()
调整为
void(*)(
)。因此参数
&func
的类型与参数的类型匹配…@BorisRasin。。。对于GCC,第二个参数类型未调整为
void(*)(
),并且非类型模板参数不能具有函数类型,因此GCC抱怨。