Workaround for the inverse of Argument Dependent Lookup?

Viewed 464

C++ has ADL (Argument Dependent Lookup) by which, as its name describes, the context (namespace) of a function can be implied from the context (namespace) of (any of) the argument(s).

fun(a); // if the type of a is in namespace ns deduce ns::f if available

My question is if the reverse is also possible by some technique? By reverse I mean if the context (namespace) can be deduced from the context of the called function. Some sort of "Function Dependent Lookup" (FDL). Fake code:

ns::fun(a); // deduce ns::a if available

I can't figure out a way of doing that. This limitation is particularly annoying for enums used to encode functions options. I would like to know if there is a technique to simulate this feature (C++11 would be ok too). Fake code:

ns::fun(Saturday, Tuesday); // Saturday/Tuesday are enum values in namespace ns;

Especially if there is a workaround for enums.

This code illustrates the issue:

namespace longname{
    class A{};
    void fun(A const& a){}
    A global_a;

    enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
    void gun(Days d1, Days d2){}    
}

int main(){
    longname::A a;
    fun(a); // cool, longname::fun(a) not necessary, fun is deduced from context

    longname::fun(global_a); // error, not cool, global_a context not deduced, 
    // must use then longname::fun(longname::global_a)
    longname::gun(Saturday, Tuesday); // error, particularly not cool, the Saturday is not deduced from context 
    // must use then longname::gun(longname::Saturday, longname::Tuesday)
    // or at best gun(longname::Saturday, longname::Tuesday)
}

EDIT: @jrok suggested a workaround based on defining nested namespace. For the enum case, I get this code. Which still has some noise (there is really no "dependent" lookup at all) but it is an improvement.

namespace longname{
    namespace days{
        enum _ { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
    }
    void gun(days::_ d1, days::_ d2){}  
}

int main(){
    using namespace longname::days; // some noise still here
    longname::gun(Saturday, Tuesday);
}

I am not using enum class because then Saturday, Sunday, etc cannot be brough directly in scope (in fact using longname::days::_ would give me a compile error)

1 Answers
Related