When is ADL applied?

喜夏-厌秋 提交于 2019-12-01 23:33:57

问题


There are 3 examples:

I.

typedef int foo;

namespace B
{
    struct S
    {
        operator int(){ return 24; }
    };
        int foo(B::S s){ return 0; }
}

int main()
{
    int t=foo(B::S()); //24, ADL does not apply
}

II.

namespace B
{
    struct S
    {
        operator int(){ return 24; }
    };
        int foo(B::S s){ return 0; }
}

int main()
{
    int t=foo(B::S()); //0, ADL applies
}

III.

namespace B
{
    struct S
    {
        operator int(){ return 24; }
    };
        int foo(B::S s){ return 0; }
}
int foo(B::S s){ return 12; }

int main()
{
    int t=foo(B::S()); //error: call of overloaded ‘foo(B::S)’ is ambiguous
                       //ADL applies
}

It is not clear for me what is the actual conditions to ADL lookup will be apply? I need in reference to standard described it.


回答1:


This Standard paragraph clarifies, and even has an example very much like your first example.

3.4.1/3:

The lookup for an unqualified name used as the postfix-expression of a function call is described in 3.4.2 [basic.lookup.argdep]. [Note: For purposes of determining (during parsing) whether an expression is a postfix-expression for a function call, the usual name lookup rules apply. The rules in 3.4.2 have no effect on the syntactic interpretation of an expression. For example,

typedef int f;
namespace N {
  struct A {
    friend void f(A &);
    operator int();
    void g(A a) {
      int i = f(a);    // f is the typedef, not the friend
                       // function: equivalent to int(a)
    }
  };
}

Because the expression is not a function call, the argument-dependent name lookup (3.4.2) does not apply and the friend function f is not found. -end note]




回答2:


Your first example does not illustrate ADL. In the line

int t=foo(B::S());

foo is typedefed to int.

The following code has some better illustrations of ADL.

#include <iostream>

namespace B
{
    struct S
    {
        operator int(){ return 24; }
    };

    int foo(S s){ return 100; }
    int bar(S s){ return 400; }
}

namespace C
{
    struct S
    {
        operator int(){ return 24; }
    };

    int foo(S s){ return 200; }
}

int bar(C::S s){ return 800; }

int main()
{
    // ADL makes it possible for foo to be resolved to B::foo
    std::cout << foo(B::S()) << std::endl;

    // ADL makes it possible for foo to be resolved to C::foo
    std::cout << foo(C::S()) << std::endl;

    // ADL makes it possible for bar to be resolved to B::bar
    std::cout << bar(B::S()) << std::endl;

    // ADL makes it possible for bar to be resolved to ::bar
    std::cout << bar(C::S()) << std::endl;
}


来源:https://stackoverflow.com/questions/23958590/when-is-adl-applied

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!