我有一個有兩種排序定義的類。 (在真正的問題中,一個是總順序,另一個是半順序。)但是,能夠使用比較運算符而不是總是使用顯式比較函數或函子對象是很好的。所以,我想我會提供一些比較操作是這樣的:詞彙範圍的排序行爲
class C;
namespace Order1 {
bool operator< (const C&, const C&);
}
namespace Order2 {
bool operator< (const C&, const C&);
}
運營商爲>
,<=
,>=
也被定義,當然,不過這不是重點。現在,用戶可以在文件範圍或塊範圍內說using namespace Order1;
或... Order2
,並獲取該文件/塊的其餘部分的請求行爲。
令人失望的部分,我想盡可能提高,這些using
s不能嵌套。在同一個命名空間中使用時
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 14:48:17
我沒有提到的一件事是,這是一個已有的類已經有這些運營商,併成千上萬的文件使用的變化。所以我堅持提供一個「默認」操作符行爲,這大部分都是舊行爲。但我想我會推薦使用顯式函數或函子的新代碼,而不是與操作符混淆。我只希望有些同事能聽取建議。 – aschepler 2010-10-21 15:21:46