I have a class with two definitions of ordering. (In the real problem, one is a total order and one is a semiorder.) But it's nice to be able to use the comparison operators rather than always having to use an explicit comparison function or functor object. So I figured I'd provide some comparison operators like this:
class C;
namespace Order1 {
bool operator< (const C&, const C&);
}
namespace Order2 {
bool operator< (const C&, const C&);
}
Operators for >
, <=
, >=
are also defined of course, but that's not the point. Now a user can say using namespace Order1;
or ... Order2
at file scope or block scope and get the requested behavior for the rest of that file/block.
The disappointing part, which I'd like to improve if possible, is that these using
s can't nest.
void g(const C&, const C&);
using namespace Order1; // for most functions in this file
void f(const C& x, const C& y) {
bool test1 = x < y; // Order1
{
// Would like to switch to Order2 for this block.
using namespace Order2;
bool test2 = x < y; // Ambiguous overload!
g(x, y); // Unaffected by local using-s.
}
}
Since using
-directives don't hide anything when used in the same namespace, this doesn't provide a way to nicely temporarily reverse the meaning of the operators for a block scope.
Another related idea would be to allow dummy objects on the stack whose constructors and destructors manipulate the "current setting" for which behavior to use. But I don't think I want to head that way for this situation, since that would mean the equivalent of f
above could change the behavior of other functions called like g
.
Is there another way to get a similar effect but allowing nested operations with the innermost block "hiding" the others? Or am I stuck with one behavior of overloaded operators per declarative region? Which I guess is manageable, since code can still explicitly use a function or functor instead of using the operators.