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

时间:2018-03-16 02:55:47

标签: c++

Here is a similar question,但是在这个问题上有效,但是,在以下情况下失败了,为什么?

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

int main()
{
  using namespace A;
  k(B::test());//compile error
}  

错误讯息为:"' A :: k'不能用作功能" (gcc 6.3.0)

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

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

引自cppref

  

首先,如果通常的非限定查找生成的查找集包含以下任何内容,则不考虑依赖于参数的查找:
  1)班级成员的声明   2)块范围内的函数的声明(不是使用声明)
  3)任何声明,它不是函数或函数模板(例如,函数对象或其名称与正在查找的函数名称冲突的其他变量)

更确切地说,using namespace A 不会引入任何声明:
引自cppref

  

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

2 个答案:

答案 0 :(得分:5)

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

  • 正常的不合格查询
  • ADL

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

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

在您的代码中,正常的非限定查找会找到A::k中所讨论的wrk -t2 -c10 -d20s --latency http://192.168.0.105:8102/get 。因此,此代码不会发生ADL。

答案 1 :(得分:2)

  

using-directive指定指定命名空间中的名称可以在using-directive之后出现using-directive的范围内使用。 在非限定名称查找(6.4.1)期间,名称看起来好像是在最近的封闭命名空间中声明的,其中包含using-directive和指定的命名空间。

因此,非限定名称查找将找到A :: k,这就是错误的原因。