我有一个类,它有两个排序定义。(在实际问题中,一个是全订单,一个是半订单。)但是,能够使用比较运算符而不是总是必须使用显式的比较函数或functor对象,这是很好的。所以我想我应该像这样提供一些比较运算符:
class C;
namespace Order1 {
bool operator< (const C&, const C&);
}
namespace Order2 {
bool operator< (const C&, const C&);
}当然,还定义了>、<=、>=的运算符,但这不是重点。现在,用户可以在文件作用域或块作用域输入using namespace Order1;或... Order2,并获得该文件/块的其余部分所需的行为。
令人失望的是,如果可能的话,我想要改进的是,这些using不能嵌套。
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.
}
}由于using-directives在同一名称空间中使用时不会隐藏任何内容,因此这不能很好地暂时颠倒块作用域中运算符的含义。
另一个相关的想法是允许堆栈上的虚拟对象,其构造函数和析构函数操作要使用的行为的“当前设置”。但我认为我不想在这种情况下这样做,因为这意味着上面的f等价物可能会改变其他调用的函数的行为,比如g。
有没有其他方法可以获得类似的效果,但允许嵌套操作与最里面的块“隐藏”其他块?还是每个声明性区域只有一个重载操作符的行为?我猜这是可管理的,因为代码仍然可以显式地使用函数或函数器,而不是使用运算符。
发布于 2010-10-21 23:11:48
我会坚持使用普通的比较函数。代码的其余部分将会更清晰。没有对作用域operator<的using namespace...或显式调用。这样读起来容易多了,我的.
int main() {
bool b = compare1(4, 5);
b = compare2(4, 5);
}发布于 2010-10-21 22:51:58
而不是使用名称空间Order2
bool test2 = Order2::operator<(x, y);它将在这种情况下工作。如果你想“元编程”,也就是能够将Order1 / Order2作为模板参数传递进来,你应该让它们成为带有operator<静态的结构(或类)。然后你可以做T::operator<(x,y),其中T是Order1或Order2。
发布于 2010-10-21 22:53:02
为什么不废弃名称空间,只声明两个具有不同参数类型的operator <重载,每个类类型一个?
更新
正如dgnorton在下面的评论中指出的,你有一个类,在它上面定义了两个不同的顺序。这看起来确实像是问题的可能原因。有没有可能把它分成两个不同的类?
https://stackoverflow.com/questions/3988565
复制相似问题