Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the ADL not working when `using directive` is used?

Tags:

c++

Here is a similar question, but in this question it works, however, it fails in the following circumstance, why?

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

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

Error message is: "'A::k' cannot be used as a function" (gcc 6.3.0)

That is to say, the compiler does not try to do ADL and never find the void k(const test&) in namespace B

However, I think the ADL should work in such situation because the code above does not belong to the following circumstance:

quoted from cppref

First, the argument-dependent lookup is not considered if the lookup set produced by usual unqualified lookup contains any of the following:
1) a declaration of a class member
2) a declaration of a function at block scope (that's not a using-declaration)
3) any declaration that is not a function or a function template (e.g. a function object or another variable whose name conflicts with the name of the function that's being looked up)

To be more precise, here the using namespace A does not introduce any declaration:
quoted from cppref

Using-directive does not add any names to the declarative region in which it appears (unlike the using-declaration), and thus does not prevent identical names from being declared.

like image 300
scottxiao Avatar asked Mar 16 '18 02:03

scottxiao


2 Answers

The name lookup for a function call has two parts:

  • normal unqualified lookup
  • ADL

According to N4659 [basic.lookup.argdep]/3, the normal unqualified lookup happens first; and then ADL stage does not go ahead if the normal unqualified lookup found:

  • a declaration of a class member, or
  • a block-scope function declaration that is not a using-declaration, or
  • a declaration that is neither a function nor a function template.

In your code the normal unqualified lookup does find A::k as discussed in your previous question. So ADL does not happen for this code.

like image 92
M.M Avatar answered Oct 05 '22 08:10

M.M


A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup (6.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.

So, unqualified name lookup will find A::k, that is the reason for the error.

like image 29
Yola Avatar answered Oct 05 '22 08:10

Yola