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
3
votes
1 answer

Undefined class template is not instantiated to check for friend functions

The following program compiles (see on godbolt), but it would not compile if we uncommented the definition of Buffer. template struct Buffer /*{ char buf[size]; }*/; template struct Wrapper { void operator+() {}…
Dr. Gut
  • 2,053
  • 7
  • 26
3
votes
1 answer

ADL name lookup problem, is using std::swap; swap(a,b) related to function overloading or inner scope function hide outer scope function?

I know what ADL is and I know in C++, inner scope function hides outer scope functions. That is, names do not overload across scopes. So funtion overloading need to be done in the same scope. So now my question is, for this common code…
Rick
  • 7,007
  • 2
  • 49
  • 79
3
votes
2 answers

Hidden friend templates in class template

The original working code I have a class template with two template parameters and an optimized operator== when the two types are the same and one another condition is satisfied. My original code is as follows (for demonstration purposes I make the…
Morwenn
  • 21,684
  • 12
  • 93
  • 152
3
votes
3 answers

Implementing member swap() in terms of non-member swap()

I'm implementing a class with a similar interface to std::array, which has both the member swap() and the non-member swap(). Since I want my class to mimic the standard containers, I would like to implement both kinds of swap() (the non-member…
Bernard
  • 5,209
  • 1
  • 34
  • 64
3
votes
3 answers

Namespace resolution with operator== in the STL

Consider a simple type, in a namespace, with an operator==: namespace ANamespace { struct Foo { int i; float f; }; } #ifdef INSIDE namespace ANamespace { bool operator==(const Foo& l, const Foo& r) { return l.i == r.i && l.f ==…
3
votes
2 answers

C++ weird templates/namespaces behavior

I had a problem compiling my code since it wasn't able to find a matching function on a template. I've narrowed down the problem to this example: namespace cv { class FileNode { }; template static inline void operator >>…
peruch
  • 33
  • 4
3
votes
1 answer

Why does ADL not work with an unnamed initializer_list?

Consider the following code. Here, if we use std::begin on an unnamed initializer_list with explicit std::, it works OK. If we omit the std:: and use begin on a named initializer_list, it also works fine. But if we omit std:: and do the rest…
Ruslan
  • 18,162
  • 8
  • 67
  • 136
3
votes
0 answers

Why is the scope operator for std namespace not required in this case?

I tried the following: #include #include int main () { std::vector myVector = {1, 2, 3, 4}; all_of(myVector.begin(), myVector.end(), [](int i){return i;}); } expecting a compilation error as I did not put std:: in…
User
  • 163
  • 6
3
votes
3 answers

How to fix previously-working injected template friend function?

I have recently updated gcc compiler from version 5 to 8, and it has broken our production code. A simplified version of the broken code is included below: #include // Imagine this has several template parameters not just Id and // this…
Andy G
  • 361
  • 1
  • 3
  • 11
3
votes
2 answers

How to provide swap() for a class in the global namespace?

For a class in a namespace the proper way to provide swap() is to define a free function in that namespace (e.g. How to overload std::swap()). But what is the best practice for a class that's in the global namespace? cppreference has an example…
Dan Stahlke
  • 1,417
  • 1
  • 15
  • 20
3
votes
1 answer

SFINAE-based Operator Overloading across Namespaces

I'm attempting to use an approach which allows for automatic enabling of bitmask operators for strongly typed enum classes. See below header and cpp of an…
3
votes
1 answer

Using namespace inside decltype

I have a function that looks more or less like this: template auto f(C const& c) -> decltype(begin(c)){ using std::begin; return begin(c); } The body of the function exploits the "using and use" idiom and thanks to the decltype,…
alfC
  • 14,261
  • 4
  • 67
  • 118
3
votes
1 answer

ADL lookup inside a class (template) member function body

struct B {}; struct C : B {}; void f(B){} // worse match than A::f struct A { template void f(T v) { f(v); // #1 } }; int main() { A{}.f(C{}); } Activating ADL lookup in line #1 is as simple as { using…
ABu
  • 10,423
  • 6
  • 52
  • 103
3
votes
2 answers

Why can an (irrelevant) using declaration reconcile overload ambiguity with Argument-Dependent Lookup?

This is a follow up of the question here on function overload with Argument-Dependent Lookup (ADL). I wanted to check my understanding of the rules under these circumstances so I wrote some test code. First, there is no swap for HasPtr class in std,…
3
votes
1 answer

Why is adl preferring the 'boost::range_detail::operator|' over the local 'operator|'?

I'm trying to write an operator| for my template class boo and everything works out fine until the template class is a boost range type - like in the example a boost::range::filter_range - adl prefers the…
TimW
  • 8,351
  • 1
  • 29
  • 33