7

This is follow up question from Does argument dependent lookup only search namespaces or classes too? , In which @David Rodríguez said "ADL will look in the enclosing namespace of the type, and also inside the type itself" . I may have got him wrong what he tried to say but I was trying this example:

struct foo{
    static void bar(foo* z){}    
};

int main(){
    foo* z;
    bar(z);
}

It doesn't compiles, producing the error " ‘bar’ was not declared in this scope " . Is it the case that ADL doesn't considers the static member function?. I mean in the example associated class is foo so wouldn't ADL look inside the class? . Can anyone please simplify the rules here?

Community
  • 1
  • 1
M3taSpl0it
  • 2,967
  • 6
  • 28
  • 27
  • 2
    Bump... the posted answer does not address the question of why ADL does not find `bar` in this code, it goes and talks about friend functions instead – M.M Apr 08 '16 at 10:28

1 Answers1

6

He probably meant this:

struct foo{
    friend void bar(foo* z){}    //not static, its friend now
};

foo* z;
bar(z); //fine now

But then technically bar() is not inside foo. It is still in the enclosing namespace of foo.

--

EDIT:

He indeed meant friend, as he said (emphasis mine):

The best example is a friend function that is defined inside the type

And his example illustrates further. Probably you need to read "defined inside", rather than only "inside".

The word "defined" is all that makes the difference, because it looks like the function's name bar is introduced into the scope of the class, but in actuality, the name bar is introduced into the enclosing namespace of foo (see §3.3.1/3-4 and §11.3/6).

Here is a better example:

namespace Demo
{
     struct foo
     {
       friend void bar(foo* z){}
     };
}

foo *z;
bar(z); //foo (type of z) is inside Demo, so is bar
        //(even though bar is defined inside foo!)

bar(NULL);    //error - NULL doesn't help ADL.
bar(nullptr); //error - nullptr doesn't help ADL.

bar(static<foo*>(NULL)); //ok - ADL

Note that the name bar, even though is introduced into the namespace Demo, is hidden, and thus cannot be used from outside using usual name-lookup:

using namespace Demo; //brings ALL (visible) names from Demo to current scope

bar(NULL); //STILL error - means bar is invisible

Or,

Demo::bar(NULL);       //error - not found
Demo::foo::bar(NULL);  //error - not found

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • But why ADL doesn't considers the static function inside the class, and ADL indeed considers the scope of class itself , isn't the case? – M3taSpl0it Feb 06 '13 at 09:22
  • @M3taSpl0it: No. As I said, it is still in the enclosing namespace of `foo`. A friend function appears to be inside in the class. The name actually declared in the enclosing namespace scope. – Nawaz Feb 06 '13 at 09:24
  • Thanks for confirmation, I appreciate you answer, can you pls backup your statement with the support of statements quoted in c++ standard contradicting my example? . Thanks – M3taSpl0it Feb 06 '13 at 09:26
  • @M3taSpl0it: Please read the section which talks about `friend` and ADL (I'm a bit busy so cannot loop it up myself). And also see the next example in my answer (which I added now). – Nawaz Feb 06 '13 at 09:31
  • @M3taSpl0it: *"P.S : your Big(O) of editing answer is way inefficient :P"*.. means? – Nawaz Feb 06 '13 at 09:37