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

Argument-dependent lookup of dependent names

This description on cppreference.com says that The lookup of a dependent name used in a template is postponed until the template arguments are known, at which time [...] ADL examines function declarations with external linkage that are visible from…
7
votes
1 answer

ADL does not work in constexpr functions (clang only)

The following code compiles with MSVC and gcc, but not with clang. Why is that so? It seems like if ADL would not work if CallFoo () is constexpr. See the comment. template constexpr void CallFoo () // Remove constexpr to fix…
Dr. Gut
  • 2,053
  • 7
  • 26
7
votes
2 answers

Why doesn't function declared inside other function participate in argument dependent lookup?

Consider a simple example: template struct tag { }; int main() { auto foo = [](auto x) -> decltype(bar(x)) { return {}; }; tag bar(tag); bar(tag{}); // <- compiles OK foo(tag{}); // 'bar' was not…
W.F.
  • 13,888
  • 2
  • 34
  • 81
7
votes
1 answer

Is it possible to create a trait to answer if a type comes from std?

After this question by utilizing ADL one can create a trait to answer if the passed type comes from our namespace: #include namespace helper { template struct is_member_of_sample : std::false_type { …
W.F.
  • 13,888
  • 2
  • 34
  • 81
7
votes
1 answer

g++, bitfields and ADL

g++ fails to compile following code snippet: namespace X { enum En {A, B}; bool test(En e); } bool check() { union { struct { X::En y:16; X::En z:16; } x; int z; } zz; return test(zz.x.y); } The error it gives is…
SergeyA
  • 61,605
  • 5
  • 78
  • 137
7
votes
2 answers

Lambdas, local types, and global namespace

This minimal program template void foo (X x) { bar (x); } template void bar (X x) { } int main () { foo ([]{}); } compiles with gcc (4.8.5 and 5.3) and fails to compile with clang (3.7) My analysis is as…
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
7
votes
1 answer

Argument-dependent lookup behaving unexpectedly on types aliased from another namespace

I just ran into some interesting behavior with argument-dependent lookup, which I do not fully understand: #include namespace a { struct Foo { Foo(int v1, int v2) : v1(v1), v2(v2) { } int v1,v2; }; } namespace b { template
mindriot
  • 5,413
  • 1
  • 25
  • 34
7
votes
1 answer

Why some Boost functions don't need prefixing with namespace

Consider this code (or the live example): #include #include #include using std::cout; int main() { boost::adjacency_list
arekolek
  • 9,128
  • 3
  • 58
  • 79
7
votes
1 answer

Range-Based For Loop and ADL

This is an extension to this question from 2011: Range-based for loops and ADL Using Visual Studio 2015, I'm not able to make a range-based for loop for a custom container using Argument Dependent Lookup (ADL). I have made a very simple test case…
Zeenobit
  • 4,954
  • 3
  • 34
  • 46
7
votes
2 answers

Confusion around function call resolution

This question is inspired by this one. Consider the code: namespace ns { template void swap(T& a, T& b) { using namespace std; swap(a, b); } } After some test with GCC, I found that swap(a, b); resolves to 1) std::swap if…
7
votes
2 answers

Is it ok to put "using std::swap;" in a header?

I've read that when you're swaping things in c++, you should always using std::swap;, then call swap unqualified, so it automatically picks the std:: ones for std:: and builtin types, your custom one for custom types, and the templated std:: one for…
Dan
  • 12,409
  • 3
  • 50
  • 87
7
votes
1 answer

Does ADL work for the global namespace?

Examples such as enabling outputting of std types explain how ADL can be used to "inject" a certain function/operator, depending on the type the fn/op is applied to. I was wondering wheter ADL fully applies to the global namespace, that is, whether…
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
7
votes
2 answers

overloading left shift operator

I have researched and found out that when you want to overload the output stream operator for cout, then the correct way to go about it is to do it this way: std::ostream& operator<<(std::ostream& os, const T& obj) This function must be defined…
Ashish K
  • 325
  • 2
  • 6
  • 12
7
votes
3 answers

Why does 'std::endl' require the namespace qualification when used in the statement 'std::cout << std::endl;", given argument-dependent lookup?

I was looking at the Wikipedia entry on argument-dependent lookup, and (on Jan 04, 2014) the following example was given: #include int main() { std::cout << "Hello World, where did operator<<() come from?" << std::endl; } ... with the…
Dan Nissenbaum
  • 13,558
  • 21
  • 105
  • 181
7
votes
3 answers

Prefer some function over ADL

I want to use range-based for to iterate over the unicode code points in a UTF8 encoded std::string. I have defined my own begin and end in the global namespace but the begin and end in the std namespace are being preferred (i.e. those found by…
uk4321
  • 1,028
  • 8
  • 18