【发布时间】:2019-12-28 22:41:19
【问题描述】:
为什么gcc HEAD 10.0.0 20190 和Clang HEAD 9.0.0 都拒绝这个程序?
#include <iostream>
void g( int x )
{
std::cout << "Hello g( " << x << " )\n";
}
template <int N>
void g()
{
std::cout << "Hello g<N>( " << N << " )\n";
}
namespace N
{
using ::g;
}
void g( int x = 20 );
template <int N = 10>
void g();
int main()
{
N::g();
N::g<>();
}
例如gcc 发出错误
prog.cc: In function 'int main()':
prog.cc:27:11: error: no matching function for call to 'g()'
27 | N::g<>();
| ^
prog.cc:9:6: note: candidate: 'template<int N> void g()'
9 | void g()
| ^
prog.cc:9:6: note: template argument deduction/substitution failed:
prog.cc:27:11: note: couldn't deduce template parameter 'N'
27 | N::g<>();
| ^
尽管根据 C++ 20(和 17)标准(9.8 使用声明)
11 [注意:对于嵌套名称说明符命名为 命名空间,在 using 声明之后添加到命名空间的成员 不在引入的声明集中,所以它们不在 在使用名称时考虑。因此,额外的重载 在 using-declaration 之后添加被忽略,但默认功能 参数 (9.2.3.6)、默认模板参数 (13.1) 和模板 考虑专业化(13.6.5、13.8.3)。 ——尾注]
根据我对标准的阅读,我认为这是一个错误。
【问题讨论】:
-
Clang 确实做了同样的事情:godbolt.org/z/Rt_FLy
-
@MaxLanghof 我自己已经测试过了。:)
-
那么我很困惑为什么这个问题特别与 gcc 有关。如果它是 gcc 中的错误,那么它也是 clang 中的错误...
-
@VladfromMoscow MaxLanghof 的观点是它在 gcc 和 clang 的 HEAD 中导致相同的错误。因此,如果 gcc 中的错误消息是错误,那么 clang 中的相同错误消息也必须是错误。如果你有一个适用的 clang 版本,那么你应该告诉它是哪个版本(提交)。
-
@VladfromMoscow 没有人说两者会/总是表现相同。但是 this 代码在 clang 和 gcc 中产生了同样的错误(当前 HEAD 在编写该注释时)。问题更多的是您为什么要专门询问编译器而不是
language-lawyer问题或类似的问题。并提到它不会在 gcc(和 clang)中编译,即使您希望它应该编译。
标签: c++ language-lawyer c++17 using-declaration