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

How to use ADL in Constraints?

As an example, I want to use a constraint to ensure that the function isinf is implemented for a template parameter T. If T is one of float, double, long double or an integral type, this can be done in the following way: #include template…
user14593414
8
votes
1 answer

Regarding friend function definition and namespace scopes

I was reading this blog post section, and I tried to play around with the snippet that was provided. namespace N { // 2 class A { friend void f(A) {} // 1 }; } If I understood correctly, the definition in // 1 will inject the name f where // 2 is…
Dante
  • 404
  • 2
  • 10
8
votes
2 answers

Rationale for Koenig lookup

What's the rationale of Koenig lookup? Cannot avoid thinking of it like something that makes your code a lot harder to read and more instable. Couldn't they define Koenig lookup so that it only work for specific cases (ie: non-member operators) or…
peoro
  • 25,562
  • 20
  • 98
  • 150
8
votes
1 answer

Why overloaded operator== for std::weak_ptr instantiated with type defined in namespace can't be found?

I'm using Visual Studio 2015. Any idea why this code compiles: #include class Foo; class Bar; typedef std::pair> Object; typedef std::vector ObjectVect; bool operator==( std::weak_ptr left, …
jpo38
  • 20,821
  • 10
  • 70
  • 151
8
votes
4 answers

Ambiguous call to templated function due to ADL

I've been bitten by this problem a couple of times and so have my colleagues. When compiling #include #include #include template< class Rng, class T > typename…
Sebastian
  • 4,802
  • 23
  • 48
8
votes
1 answer

template object's template friend functions and namespaces

In the following C++ example code, GCC 6 and Clang 3.8 disagree on what the correct behaviour is: This contrived example "works" -- as in the test() function returns o.p in GCC. In clang, it calls the (undefined) function get
Matt Godbolt
  • 1,381
  • 11
  • 14
8
votes
1 answer

Argument dependent lookup for friend functions

Consider the following: namespace N { struct A { }; struct B { B() { } B(A const&) { } friend void f(B const& ) { } }; } int main() { f(N::B{}); // ok f(N::A{}); // error } In the first case, the case…
Barry
  • 286,269
  • 29
  • 621
  • 977
8
votes
3 answers

Nested class strange function lookup: surrounding class functions hide global functions

I have the following simplified code namespace Namespace { int foo() { return 1; } class Class { public: int foo() const { return 2; } class Nested { public: Nested() { cout << foo() << endl; } …
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
8
votes
4 answers

find() using overloaded operator==

I try to find an element in a vector using overloaded operator==(). However, if using type1 in the following code, the output is 1 and 0 (not found). Using type2 gives both 1 and 1. The environment is Xubuntu 12.04 and g++ version 4.6.3. #include…
8
votes
2 answers

No ADL inside decltype on VS2012

I just realized that trying to get the return type of a function via decltype does not involve ADL (argument-dependent-lookup) on VS2012 (tested using cl.exe V17.00.60610.1). The following example #include #include namespace A…
mmmmmmmm
  • 15,269
  • 2
  • 30
  • 55
8
votes
1 answer

Argument-dependent lookup through base of a template class

I have a template class NB::B derived from a non-template class NA::A in a namespace. act is a template function calling add_ref function on an instance of its template argument. Specifically, act> wants to find add_ref defined in…
Nicht Verstehen
  • 421
  • 2
  • 11
7
votes
4 answers

How to make a function template the least priority during ADL?

I have a problem where I'd like to provide a generic version of a function foo which may only be applied when there is absolutely no other match for an invocation. How can I modify the following code such that last_resort::foo is a worse match for…
Jared Hoberock
  • 11,118
  • 3
  • 40
  • 76
7
votes
1 answer

Why do `std::ranges::size` require a non-const method when using ADL?

Otherwise, size(t) converted to its decayed type, if ranges::disable_sized_range> is false, and the converted expression is valid and has an integer-like type, where the overload resolution is performed with the following…
zjyhjqs
  • 609
  • 4
  • 11
7
votes
2 answers

Do custom container iterators guarantee ADL to consider namespace std?

I have no intention of using this in real code. I promise. Does the standard guarantee that std namespace is going to be found when a function argument is of type container::iterator and container::iterator isn't a typedef for a built-in type? For…
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
7
votes
1 answer

Dependent template names and C++20 ADL

Consider the following example: namespace N { template struct C { }; template void foo(C); } template void bar(N::C c) { foo<0>(c); } int main() { N::C c; bar(c); } Both GCC…
Evg
  • 25,259
  • 5
  • 41
  • 83