C ++函数到指针的隐式转换:哪个编译器正确?铛和海湾合作委员会不同意

时间:2019-06-07 17:51:34

标签: c++ gcc clang

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)进行编译。

海湾合作委员会说: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()似乎是“模板非类型参数的有效类型”

1 个答案:

答案 0 :(得分:6)

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

  

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

所以c是正确的。 GCC错误报告已经存在bug #82773


只有c ++标准的当前工作草案才能将模板参数substitution转换为以下模板参数的过程。因此,可以说该标准尚不明确,因为它没有指定在每个替换之后都进行类型调整。