c++ - 使用声明 : one more bug of gcc and clang?

标签 c++ language-lawyer c++17 using-declaration

为什么 gcc HEAD 10.0.0 20190Clang 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 using 声明)

11 [Note: For a using-declaration whose nested-name-specifier names a namespace, members added to the namespace after the using-declaration are not in the set of introduced declarations, so they are not considered when a use of the name is made. Thus, additional overloads added after the using-declaration are ignored, but default function arguments (9.2.3.6), default template arguments (13.1), and template specializations (13.6.5, 13.8.3) are considered. — end note]

根据我对标准的阅读,我认为这是一个错误。

最佳答案

此问题是 Core issue 1907 的主题.目前的方向是将此类病例视为畸形病例,无需诊断。

事实证明,一些实现在“每个实体”的基础上跟踪默认参数(因此很难不考虑在以后的重新声明中添加的默认参数),而其他实现则在“每个声明”上跟踪它们基础(所以很难让他们考虑这样的默认参数)。 CWG 决定通过对依赖于此类 IFNDR 的代码进行分类来适应这两种实现策略。

关于c++ - 使用声明 : one more bug of gcc and clang?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57629112/

相关文章:

c++ - 模板的非类型参数

c++ - 具有唯一元素和按索引访问的容器

c++ - 模板偏序 - 为什么部分推导在这里成功

c++ - 类成员转换函数-id

c++ - 为什么我不能更改新创建文件的 'last write time'?

c++ - 递归折叠参数包以解析占位符类型

c++ - 为什么在用花括号初始化结构时会出错?

进入循环期间 for 循环中的 C++ 段错误

c++ - C++ 标准中与 [basic.link]/7 相关的 GCC 和 clang 之间的矛盾结果

c++ - 带有兰数的彩票程序