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
5
votes
0 answers

How to consider ADL for type of non-type template parameters

I want to consider functions in the namespace of non-type template parameters during lookup in a function call. For example: template struct test_nontype { int call() { return f(*this); // error: 'f' was not declared in this…
Artyer
  • 31,034
  • 3
  • 47
  • 75
5
votes
1 answer

Does std::(customization point) invoke the most appropriate overload?

Since C++20, the concept of customization point is introduced in [namespace.std]/7: Other than in namespace std or in a namespace within namespace std, a program may provide an overload for any library function template designated as a…
xskxzr
  • 12,442
  • 12
  • 37
  • 77
5
votes
1 answer

Two-phase function template compilation: not *only* ADL is employed in the 2nd phase?

I'm wondering why the following code compiles. #include template void print(T t) { std::cout << t; } namespace ns { struct A {}; } std::ostream& operator<<(std::ostream& out, ns::A) { return out << "hi!"; } int…
5
votes
2 answers

Using equality operators with boost::optional

I'm trying to define an equality operator for a type T defined in another namespace, and then use the equality operator on optional. On clang (Apple LLVM 9.1.0), this code: namespace nsp { struct Foo { }; } bool…
Mohan
  • 7,302
  • 5
  • 32
  • 55
5
votes
1 answer

Call to function is ambiguous when irrelevant type defined as alias

After reading of a great article True Story: Efficient Packing I tried to implement tuple by myself as exercise: #include #include #include template< std::size_t I, typename T > struct tuple_leaf { T value;…
Tomilov Anatoliy
  • 15,657
  • 10
  • 64
  • 169
5
votes
2 answers

C++ operator overloading and associated namespace

The following simplified example compiles in gcc and Visual Studio, but fails in clang !? namespace N { struct A {}; template double operator+ (T a, double d) {return d;} template double operator+…
5
votes
1 answer

How does the compiler find the template function X::max(T const&, T const&) through ADL in the code below?

A quote from the Standard is appreciated. #include namespace X { class A {}; } template inline T const& max(T const& a, T const& b, T const& c) { return max(max(a, b), c); } inline X::A const& max(X::A const& a,…
5
votes
2 answers

`decltype` and mixing ADL-lookup with non-ADL-lookup

Testcase Let the return type of a function auto foo(T f) be the same as when calling sin(f) from header cmath in cases where f is an intrinsic datatype: template auto foo(T f) -> decltype(sin(f)) { using std::sin; return…
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
5
votes
1 answer

Why can't the compiler find this operator<< overload?

I'm trying to write overloads of operator<< for specific instantiations of standard library containers that will be stored in a boost::variant. Here's a small example that illustrates the problem: #include #include std::ostream…
5
votes
1 answer

Understanding the scope of operators in C++

#include namespace Foo { class Baz { }; std::ostream& operator<< ( std::ostream& ostream , const Baz& baz ) { return ostream << "operator<<\n"; } } int main() { std::cout << Foo::Baz(); } I define an…
Kolyunya
  • 5,973
  • 7
  • 46
  • 81
5
votes
2 answers

Why does C++11 not support name lookup like this?

struct A { enum InnerEnum { X }; A(InnerEnum x) {} }; int main() { A a(X); } The compiler complains: error C2065: 'X' : undeclared identifier The compiler knows what the constructor's parameter type is, so when I pass X as the…
xmllmx
  • 39,765
  • 26
  • 162
  • 323
5
votes
2 answers

Determining return type of "generic function"

Suppose, I want to develop a generic library which should be usable with number-like types including double and user-defined types. The problem, I'm facing right now is that I don't know how to write the return type of a function template much like…
4
votes
2 answers

ADL fails when there are lambda arguments?

quite some time ago i noticed that in Visual C++ 10 ADL fails when at least one of the arguments is a lambda. std::vector vec; for_each(begin(vec), end(vec), [](float) {}); The above fails to compile on VC++10 and 11 (beta) (begin and end…
4
votes
1 answer

Which functions in standard C++ library should not be prefixed with std:: when used?

When I program in C++, instead of writing using namespace std;, I generally tend to use std:: prefixed components like std::cout, std::cin etc. But then I came across ADL and why you should use using std::swap;. Many components of the standard…
4
votes
1 answer

Is there a hack to defer non-ADL name lookup to the point where a C++ concept is used?

I'm trying to use a concept that applies to both built-in and user-defined types. In my setting, it is inconvenient to forward-declare certain functions (because the functions depend indirectly on the concepts causing my problem). My problem is…
user3188445
  • 4,062
  • 16
  • 26