Questions tagged [argument-dependent-lookup]

A form of name lookup in C++ which allows function names to be found in namespaces associated with the arguments used in the function call.

An unqualified function call such as func(a, b, c) will lookup the name func in the namespaces that are associated with the types of the arguments a, b and c. For example, if a has type ns::A and a function ns::func exists then it can be found by argument dependent lookup and will be added to the overload set used to resolve the call.

The reason for this feature is to allow overloaded operators declared in namespaces to be found, because operators cannot be qualified by a namespace e.g.

namespace ns
{
  struct A { };

  A operator+(const A&, const A&);
}

void f(ns::A a1, ns::A a2)
{
  ns::A sum = a1 + a2;   // must find ns::operator+
}

In the example above the + operator must find ns::operator+, but without ADL it would not.
ADL allows the natural a1 + a2 syntax to work as expected, instead of having to write something like a2 ns::+ a2, which isn't valid syntax, or ns::operator+(a1, a2).

ADL is sometimes known as "Koenig Lookup" after Andrew Koenig, who suggested the feature.

367 questions
7
votes
3 answers

ADL in case of equal-named member function

The situation is that some member function bar::Bar::frobnicate wants to utilize ADL to find a function from some unknown namespace, within a function that has an identical name. However, it only finds its own name. Testcase (Note that in reality,…
7
votes
1 answer

Doesn't ADL looks up static member functions?

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…
M3taSpl0it
  • 2,967
  • 6
  • 28
  • 27
7
votes
1 answer

Argument-dependent lookup -- when is it done, what is searched, and how can you force (or prevent) it?

I'm having trouble understanding the rules behind argument-dependent (Koenig) lookup. Consider the code below: #include using namespace std; namespace adl { struct Test { }; void foo1(Test const &) { cout << "ADL used (foo1)"…
user541686
  • 205,094
  • 128
  • 528
  • 886
7
votes
2 answers

Why does ADL take precedence over a function in 'std namespace' but is equal to function in user-defined namespace?

I have two snippets for ADL for demo purposes. Both snippets have been compiled by VC10, gcc & comeau C++ compilers, and the result are the same for all three. <1>ADL against using directive of a user defined namespace: #include…
RoundPi
  • 5,819
  • 7
  • 49
  • 75
7
votes
1 answer

Argument-dependent lookup in C++

How does this work? Is it related to ADL? #include template struct A { friend void f(T x) { std::cout << "A\n"; } }; int main() { f(new A()); } Can somebody tell me why i can't use something…
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
6
votes
1 answer

Why doesn't `static_pointer_cast` work with ADL, but requires explicit `std::`?

Consider // https://godbolt.org/z/z5M9b9jzx #include #include struct B {}; struct D : B {}; int main() { std::shared_ptr b = std::make_shared(); auto d = static_pointer_cast(b); assert(d); } I'd've expected…
6
votes
2 answers

How does ADL affect this piece of C++ code?

Actually, the below code can not be compiled with Clang using this command: clang++ -std=c++11 test.cc -o test. I just want to mimic the same behavior as "swapping idiom" in C++ to use "using-directive" to enable ADL. But where am I wrong with the…
Jason Yu
  • 1,886
  • 16
  • 26
6
votes
1 answer

C++ ADL in nested namespaces with template function

I have a question regarding the standard ADL resolution in C++. Here is a sample code explaining my enquiry: #include // The mechanism: namespace A { template< class C > ::std::string scope(const C*) { return "A"; } namespace B { …
DocZeD
  • 63
  • 5
6
votes
1 answer

ADL with std::function: Can functions taking std::function objects be found via the types in the std::function's argument list?

Consider the following code snippet: #include namespace ns { struct Arg{}; using Func = std::function; Func operator+(Func lhs, Func rhs) { return [lhs, rhs](Arg arg) { return lhs(arg) +…
6
votes
2 answers

Should this function call be ambiguous?

I stumbled on this the other day and can't figure out which answer is correct, or whether both are acceptable. Specifically, I'm referring to the call to bar(T{}) in OtherFunction. From what I've been able to test on compiler explorer, the decision…
6
votes
1 answer

Range-based for loops and ADL

The C++0x standard working draft states (section 6.5.4) the following about the begin() and end() calls that are implicit in a range-based for loop: 'begin' and 'end' are looked up with argument-dependent lookup (3.4.2). For the purposes of…
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
6
votes
1 answer

ADL and friend injection

Consider this code: template struct X { friend void f(X *) {} }; int main() { f((X<0> *)0); // Error? } compilers seem to heavily disagree. (MSVC08/10 says no, GCC<4.5 says yes, but 4.5 says no, sun 5.1 says yes, intel 11.1 says yes too…
uj2
  • 2,255
  • 2
  • 21
  • 32
6
votes
2 answers

Argument-dependent lookup and function templates

Here is an example: #include #include #include using std::string; int main() { string str = "This is a string"; // ok: needn't using declaration, ADL works auto it = find(str.begin(), str.end(), 'i'); …
6
votes
1 answer

Why doesn't a using directive affect ADL?

I am trying to understand why the following code does not compile: namespace ns { struct S {}; } namespace alleq { inline bool operator==(const ns::S &, const ns::S &) { return true; } } namespace ns { using namespace alleq; //…
user3188445
  • 4,062
  • 16
  • 26
6
votes
5 answers

why swap() can work well when I don't call it with two pointer?

#include using namespace std; void swap(int *a, int *b) { *a = *a^*b; *b = *a^*b; *a = *a^*b; } int main() { int array[]={1,9,2,8,3,7}; for(int i=0; i<6; i++) cout<
city
  • 2,036
  • 2
  • 32
  • 40