Argument-dependent search - when it's done, what were you looking for, and how can you force (or prevent) it?

I'm having trouble understanding rules that depend on argument dependent (Koenig).

Consider the code below:

#include <iostream> using namespace std; namespace adl { struct Test { }; void foo1(Test const &) { cout << "ADL used (foo1)" << endl; } void foo2(Test const &) { cout << "ADL used (foo2)" << endl; } void foo3(Test const &) { cout << "ADL used (foo3)" << endl; } } struct foo1 { foo1() { } template<class T> foo1(T const &) { cout << "ADL not used (foo1)" << endl; } template<class T> void operator()(T const &) const { cout << "ADL not used (foo3)" << endl; } }; template<class T> void foo2(T const &) { cout << "ADL not used (foo2)" << endl; } int main() { adl::Test t; foo1 foo3; (foo1(t)); (foo2(t)); (foo3(t)); } 

His conclusion:

ADL is not used ( foo1 )
Used by ADL ( foo2 )
ADL is not used ( foo3 )

I expected all of them to use ADL, but I was surprised that only a few of them did.

What are (potentially burning, I know) the details behind ADL rules?
I understand the concept quite well, but the details are what I came across.

What search areas are viewed when they are being performed, and when they are not being searched?

Is it even possible to determine if ADL is being used without looking at all the #include 'files before a given line of code? I expected functors and functions to behave the same in terms of [not] masking ADL, but apparently they do not.

Is there a way to force ADL in cases when it does not run automatically (for example, above), and you do not know the class namespaces (for example, in a template)?

+6
source share
1 answer

Your problem is not related to the search argument dependent. First of all, an argument-dependent search can get into the image only with an unconditional search for functions. When foo1(t) foo1 is a type and its template constructor is called. Similarly, foo3(t) is a qualified search, because foo3 is an object, and the function call operator is looked up in the object class foo1 . The only place where the argument search enters the image is foo2(t) , where the search finds candidates:

  • ::foo2<adl::Test>(adl::Test const&)
  • ::adl::foo2(adl::Test const&)

These two functions are passed to overload resolution, and since both functions are equally good, a function without a pattern wins.

There are actually three questions to your question:

  • The details of finding a name are too broad, and so this question is a request for an essay that I ignore.
  • You second question expands to three questions, only one seems relevant:
    • What search areas are performed? When searching for an unqualified function name within a function definition, the rules depend on whether any of the names is a dependent name. If there is no such name (for example, in code without a template or in template code where names can be specified in the first phase), the name is looked up in the namespace and in the namespaces associated with its argument. Otherwise, the name is viewed only in the associated namespaces.
  • Can forced search for dependent arguments? This is always done to look for unqualified functions if there is at least one argument, but names found differently may be better match. Of course, you need to call an unqualified function, otherwise it will not be done.
+5
source

All Articles