我有一个有两个排序定义的类。 (在实际问题中,一个是总顺序,一个是半自由。)但是能够使用比较运算符而不是总是必须使用显式比较函数或函子对象是很好的。所以我想我会提供一些这样的比较运算符:
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
- 指令在同一名称空间中使用时不会隐藏任何内容,因此这不能提供一种方法来很好地暂时反转块作用域的运算符的含义。
另一个相关的想法是允许堆栈上的虚拟对象,其构造函数和析构函数操纵“当前设置”以使用哪种行为。但我认为我不想为这种情况采取这种方式,因为这意味着相当于上面的f
可能会改变其他函数的行为,如g
。
是否有其他方法可以获得类似的效果,但允许嵌套操作与最里面的块“隐藏”其他?或者我是否坚持每个声明区域的重载运算符的一个行为?我认为这是可管理的,因为代码仍然可以明确地使用函数或函子而不是使用运算符。
答案 0 :(得分:2)
我会坚持普通的比较功能。其余代码将更清晰。没有using namespace...
或显式调用作用域operator<
。以这种方式阅读更容易,IMO ......
int main() {
bool b = compare1(4, 5);
b = compare2(4, 5);
}
答案 1 :(得分:0)
而不是使用命名空间Order2放入
bool test2 = Order2::operator<(x, y);
将在此实例中起作用。如果你想要“元程序”,即能够传递Order1 / Order2作为模板参数,你应该使用运算符&lt;它们来构造它们的结构(或类)。静态的。然后你可以做T :: operator&lt;(x,y),其中T是Order1或Order2。
答案 2 :(得分:0)
为什么不废弃命名空间,只声明两个具有不同参数类型的operator <
重载,每个类类型一个?
<强>更新强>
正如dgnorton在下面的评论中指出的那样,你有一个类,其上定义了两个不同的排序。这似乎是问题的可能原因。是否可以将其拆分为两个不同的类?