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
10
votes
2 answers

What is the rationale behind ADL for arguments whose type is a class template specialization

I've spent some time trying to realize why my code doesn't compile and I've realized that in C++ Argument Dependent Lookup uses template typename arguments to determine name lookup scope. #include #include namespace myns { …
witosx
  • 614
  • 4
  • 15
10
votes
3 answers

What is the best namespace for a binary operator?

For elegance, encapsulation and to exploit ADL (Argument Dependent Lookup) is common to define a function inside the namespace of the function argument. Suppose I have two libraries in different namespace. There are three cases 1) one is part of a…
alfC
  • 14,261
  • 4
  • 67
  • 118
9
votes
1 answer

3.4.2 Argument-dependent name lookup from n3290 Draft

A point from ISO draft n3290 section 3.4.2 paragraph 1: When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual unqualified lookup may be searched, and in those namespaces,…
user751747
  • 1,129
  • 1
  • 8
  • 17
9
votes
3 answers

Why is std::swap not using swap idiom?

As proper use of std::swap is: using std::swap; swap(a,b); It is a bit verbose but it makes sure that if a,b have better swap defined it gets picked. So now my question is why std::swap is not implemented using this technique so user code would…
9
votes
2 answers

Can't understand name lookup differences between an int and a user defined type - perhaps ADL related

Why does the following code compile: template void foo(T in) { bar(in); } struct type{}; void bar(type) {} int main() { foo(type()); } When the following does not: template void foo(T in) { bar(in); } void bar(int) {} int…
9
votes
1 answer

ADL fails (or not done?) for function with additional (non deduced) template parameter

namespace N { class C {}; template char const * found(X && x) { return "found"; } template char const * notfound(X && x) { return "not found"; } } This defines a…
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
9
votes
1 answer

Inconsistencies with conditional noexcept and overloads

I have an issue which is quite similar to this one. In short, I have a magic method, which is noexcept if another method is noexcept. The weird thing is that this "another method" has two overloads, and the compiler chooses the second overload to…
Dante
  • 404
  • 2
  • 10
9
votes
5 answers

Why was argument dependent lookup invented?

Why was argument dependent lookup (ADL) invented? Is it just so we can write cout << stuff instead of std::operator<<(cout, stuff)? If that is the case, why wasn't ADL limited to operators instead of all functions? Could the introduction of ADL have…
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
9
votes
1 answer

friend function template lookup

According to the standard, friend function declared and defined in class can only be find by ADL. So, I think the following code should compile. template struct test{ template friend void foo(test){} }; int main(){ …
9
votes
3 answers

Overload operator>> for std::pair

I am trying to use boost::lexical_cast on a std::pair. #include #include #include namespace my { // When my_pair is a user defined type, this program compiles // and runs without any…
thegameg
  • 281
  • 4
  • 14
9
votes
1 answer

Can refactoring an overloaded operator into a non-member function break any code?

Consider a legacy class template with overloaded addition operators += and + template class X { public: X() = default; /* implicict */ X(T v): val(v) {} X& operator+=(X const& rhs) { val += rhs.val; return *this; } …
9
votes
2 answers

Why will two-phase lookup fail to choose overloaded version of 'swap'?

I am studying this fascinating answer to a subtle question regarding the best practice to implement the swap function for user-defined types. (My question was initially motivated by a discussion of the illegality of adding types to namespace…
Dan Nissenbaum
  • 13,558
  • 21
  • 105
  • 181
9
votes
1 answer

Workaround for the inverse of Argument Dependent Lookup?

C++ has ADL (Argument Dependent Lookup) by which, as its name describes, the context (namespace) of a function can be implied from the context (namespace) of (any of) the argument(s). fun(a); // if the type of a is in namespace ns deduce ns::f if…
alfC
  • 14,261
  • 4
  • 67
  • 118
8
votes
1 answer

Argument-dependent lookup for templates in C++20

The program as follows compiles fine in C++20: #include struct A{ virtual ~A() = default; }; struct B: A {}; int main() { std::shared_ptr p = std::make_shared(); auto x = dynamic_pointer_cast(p); } But in C++17 it…
Fedor
  • 17,146
  • 13
  • 40
  • 131