当使用`using directive`时,为什么ADL不工作?

big*_*iao 5 c++

这是一个类似的问题,但是在这个问题中它有效,但是,它在以下情况下失败了,为什么?

namespace A
{
  int k;
}
namespace B
{
  class test{};
  void k(const test&){/*do something*/}
}

int main()
{
  using namespace A;
  k(B::test());//compile error
}  
Run Code Online (Sandbox Code Playgroud)

错误信息是: "'A :: k'不能用作函数"(gcc 6.3.0)

也就是说,编译器不会尝试执行ADL,也不会找到void k(const test&)innamespace B

但是,我认为ADL应该在这种情况下工作,因为上面的代码不属于以下情况:

引自cppref

首先,将参数相关的查找不被认为是如果通过通常的不合格查找产生的查找组包含任何以下的:
1)一个声明类成员
2)声明在块范围的函数的(这不是一个using声明)
3)任何声明这不是一个函数或函数模板(例如,功能对象或其他变量,其名称冲突与同时被查找的功能名称)

更确切地说,这里using namespace A 没有引入任何声明:
引自cppref

using-directive不会向它出现的声明区域添加任何名称(与using-declaration不同),因此不会阻止声明相同的名称.

M.M*_*M.M 6

函数调用的名称查找包含两部分:

  • 正常的不合格查找
  • ADL

根据N4659 [basic.lookup.argdep]/3,正常的非限定查找首先发生; 如果找到正常的非限定查找,则ADL阶段不会继续:

  • 集体成员的声明,或
  • 块范围函数声明,它不是using声明,或
  • 既不是函数也不是函数模板的声明.

在您的代码中,正常的非限定查找确实找到A::k您在上一个问题中所讨论的内容.因此,此代码不会发生ADL.