就像前面說的那樣, 比較運算符的定義存在一個小的問題. 依賴於返回值和預期的順序,有許多方式來定義它們,這就是為什麼這些運算符的含義沒有一次性固定
運算符定義的方式會受到策略的影響, 就像是已經存在的針對於捨入和檢查的情況. 然而, 比較是這個類的外部的性質而不是一個內部的性質。獨立於區間的類型,它們可能會被局部修改。
每次都會定義運算符<, <=, >,
>=, ==, !=;
就像算術操作符那樣,它們可以帶有一個基類型的參數,然而由於技術的限制,這個基類型的參數只能是第二個參數,所以,這些運算符不是語義上完整的,返回值不是永遠為bool類型, 因為一些有趣的結果可以通過一個三態bool類型來獲得,下面是運算符簽名的一般形式。
template<class T, class Policies1, class Policies2> return_type operator== (const interval<T, Policies1>&, const interval<T, Policies2>&); template<class T, class Policies> return_type operator== (const interval<T, Policies>&, const T&);
如果沒有指定任何規則,比較運算符的意義是基類型的比較運算符意義的擴展,更精確一點,如果其中一個參數是非法的或是一個空區間,將會拋出一個異常,如果參數是合法的,下面的規則用於決定
[a,b] op [c,d]的結果(考慮
c == d 如果第二個參數是T類型):
(x op
y), 那麼結果為 true!(x op
y), 那麼結果為 false這些比較運算允許使用區間類型來替換基類型而不改變程序的含義,實際上,如果沒有拋出異常,結果與先前是一樣的,如果有異常拋出,先前的比較是不確定的,並且需要改寫 .
其它的比較通過使用名字空間來選擇,這些名字空間位於boost::numeric::interval_lib::compare並且被
:
using namespace boost::numeric::interval_lib::compare::the_comparison_to_select;調用
在這一行代碼之後,運算符的默認含義將會被這個名字空間中的運算符的默認含義所取代,請注意:由於C++的名字查找規則,一個接一個地使用兩個名字空間是不可能的,而且它們必須在不同的代碼層次中,否則的話,編譯器將會指出存在二義性的運算符,總結如下:
// 例 1: BAD
using namespace compare1;
...
using namespace compare2;
...
// 例 2: GOOD
{ using namespace compare1;
... }
{ using namespace compare2;
... }
// 例 3: BAD
using namespace compare1;
...
{ using namespace compare2;
... }
下面是一些已提供的比較的列表,它們都位於<boost/numeric/interval/compare/...>之下相應的頭文件中. 作為默認的比較運算,如果傳遞了非法的參數,這些運算符將會拋出異常。
certain: 這種比較等價於默認的比較方式,將異常情況映射為false. 因此,僅當每一對元素的比較都為真時這些運算符才會返回true.possible: 異常情況被映射為 true. 一旦有一對元素的比較通過,運算符將會立即返回true。lexicographic: 詞典序(lexicographic order)(首先比較下界,如果還不足以知道結果,就會比較上界). 這種順序在區間運算中是沒有意義的,然而,因為它是數對的自然全序,在某些情況下它可能還是很有用的。set: 集合包含偏序(the set inclusion partial order). 這一次,一個空區間不再被看作是非法的(但是一個非法的數字仍然是非法的). <= 和 <是子集(subset)
和真子集(proper subset)關係; >= 和 >
是超集(superset)和真超集(proper superset)關係.tribool: 這種比較依賴於Boost tristate
boolean庫並且改變默認的運算符,使得一個明確的未定義值返回一個三態bool值來取代拋出一個異常。
namespace boost {
namespace numeric {
namespace interval_lib {
class comparison_error: std::runtime_error; // "boost::interval: uncertain comparison"
} // namespace interval_lib
} // namespace numeric
} // namespace boost
在某些情況下,你可能想要直接的比較邊界值並且避免默認的運算符中出現的未定義的情況,針對這一目的提供了一些函數,它們期望參數是合法的,當只進行了一次比較之後就返回結果,它們的名字被cer修飾(意義為 "certain", 如果默認比較為true,結果就為true)或pos(意義為 "possible",如果默認的比較為false,結果就為false)
接下來是 lt, le, gt,
ge, eq or ne,它們位於<boost/numeric/interval/compare/explicit.hpp>中. 每一個函數都帶有兩個參數並返回一個bool值; 這些函數期望參數是合法的,否則的話可能有未定義的行為,例如,比較的定義是
namespace boost {
namespace numeric {
namespace interval_lib {
template<class T, class Policies1, class Policies2>
bool cerlt(const interval<T, Policies1>& x, const interval<T, Policies2>& y);
template<class T, class Policies>
bool cerlt(const interval<T, Policies>& x, const T& y);
template<class T, class Policies>
bool cerlt(const T& x, const interval<T, Policies>& y);
} // namespace interval_lib
} // namespace numeric
} // namespace boost
Revised 2006-12-24
Copyright © 2002 Guillaume Melquiond, Sylvain Pion, Hervé
Brönnimann, Polytechnic University
Copyright © 2003 Guillaume Melquiond
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)