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 enum
s 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 enum
s.
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)