c++ - C++ 函数到指针隐式转换:哪个编译器是正确的?Clang 和 GCC 不同意
问题描述
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()
似乎是“模板非类型参数的有效类型”
解决方案
与函数参数类型发生的情况类似,如果非类型模板参数的类型是函数类型,则将其调整为指向函数类型[temp.param]/8的指针:
将类型为“T 数组”或函数类型 T 的非类型模板参数调整为“指向 T 的指针”类型。
所以clang是对的。GCC 错误报告已经存在错误 #82773
只有当前的 c++ 标准工作草案承认将模板参数替换为以下模板参数的过程。因此可以说该标准并不明确,因为它没有指定在每次替换后执行类型调整。
推荐阅读
- c - 试图将 conio 链接到我的 makefile。make return 找不到 -lconio
- c++ - 在大数据上使用 boost filtering_streambuf
- c - 如何获取结构的结构信息
- java - 仅当元音不以单词开头时才删除
- woocommerce - 有条件地隐藏定价;需要从标签/自定义分类中可见
- c++ - 我在理解 AVX shuffle 内在函数如何为 8 位工作时遇到一些问题
- javascript - 使用时刻检查时间是否介于两次之间无法正常工作
- google-apps-script - 在 Google Apps 脚本中,是否可以使用 try/catch 捕获超时,或者它是否发生在更高级别?
- javascript - 使用猫鼬在 mongodb 中按月收集?
- java - 如何处理具有 2 个输入和 2 个输出的过程的错误异常?