Sort of reverse Argument Dependent Lookup in C++

19 hours ago 4
ARTICLE AD BOX

I am pretty sure the feature I am looking for doesn't exist in C++, but maybe there are smart alternatives that do something similar.

In C++, we have Argument Dependent Lookup (ADL) feature, also known as Koenig Lookup, for example explained here. This is an example:

namespace Foo { struct A{}; void callA(A a) {} } int main() { using Foo::A; callA(A{}); // OK }

Several times already I wished I can write something similar but inverting the role of the function and its argument:

namespace Foo { class A{}; void callA(A a) {} } int main() { using Foo::callA; callA(A{}); // doesn't compile, 'A' is not found }

Intuitively to me, it would make sense that callA could find the constructor of Foo::A in its argument since it belongs to Foo namespace. But that is not the case.

The real case usage I try to solve is more something like this:

#include <vector> namespace detail { using someCollection = std::vector<int>; enum { sorted }; enum { reversed }; void iterate(someCollection&); void iterate(someCollection&, decltype(sorted)); void iterate(someCollection&, decltype(reversed)); } using detail::iterate; int main() { std::vector<int> v; iterate(v); // OK iterate(v, sorted); // Error: 'sorted' undefined iterate(v, detail::sorted); // OK, but ugly using detail::reversed; iterate(v, reversed); // OK, but auto a = reversed; // I wish to limit the scope of 'reversed' }

What I tried is to have an enum value (or a constexpr constant, or an empty struct ) to be private to a function call. In previous example, sorted and reversed are dummy values only used for their unique types. They only make sense in calls to iterate, otherwise they are just polluting global namespace.

Is there some clever work around?

Read Entire Article