
對於每個概念,都有一個概念檢查類用於確認一個給定類型(或一組類型)是否符合該概念。Boost概念檢查庫(BCCL)包括了對應於所有C++標準庫中所使用的概念的概念檢查類,另外還新增一些。Reference參考 一節列出了這些概念檢查類。另外,其它boost庫也可能帶有該庫所用概念的概念檢查類。例如有 graph concepts圖概念 和 property map concepts屬性映射概念. 還有,任何時候任何人編寫了一個函數模板,其中的類用到了目前還不存在的概念時,都應該創建一個新的概念檢查類。如何創建,請見 Creating Concept Checking Classes創建概念檢查類.
下面以 BCCL 的 EqualityComparableConcept 類為例說明概念檢查類。該類對應於C++標準 20.1.1
節中所描述的 EqualityComparable 要求,以及SGI STL文檔中的 EqualityComparable
概念。
template <class T>
struct EqualityComparable;
模板參數 T 為要檢查的類型。即,EqualityComparable<X> 的作用是確認 X 符合 EqualityComparable 概念。
檢查概念要求的最通用方法是使用
BOOST_CONCEPT_ASSERT() 宏。你可以在任何域中使用這個宏,傳入一個用括號括起來的概念檢查模板的特化。注意:這意味著對 BOOST_CONCEPT_ASSERT 的調用要使用雙重括號。
// 在我的庫中:
template <class T>
void generic_library_function(T x)
{
BOOST_CONCEPT_ASSERT((EqualityComparable<T>));
// ...
};
template <class It>
class generic_library_class
{
BOOST_CONCEPT_ASSERT((RandomAccessIterator<It>));
// ...
};
// 在用戶代碼中:
class foo {
//...
};
int main() {
foo x;
generic_library_function(x);
generic_library_class<std::vector<char>::iterator> y;
//...
}
在建議的C++0x中關於 聲明函數模板的概念約束的語法 中,有一個不錯的東西,就是該約束是函數聲明的一個組成部分,所以客戶可以看見它們。BOOST_CONCEPT_ASSERT 只能在函數模板定義中給出約束,這樣約束就被隱藏在函數體裡面。除了沒有自聲明的接口外,如果函數是在被調用的編譯單元以外的編譯單元被顯式實例化的,或者編譯器實現了鏈接期實例化,那麼這種只在函數體中使用斷言的方法可能會引起不想要的檢查延遲。
BOOST_CONCEPT_REQUIRES 宏可以用在函數模板聲明中,檢查某個類型是否符合某個概念。它接受兩個參數,一個約束列表,和一個函數模板的返回類型。約束列表的形式是,一系列相連的概念檢查模板特化,以雙重括號包圍,而函數的返回類型也必須用括號括起來。例如,標準的 stable_sort
算法可以聲明如下:
template<typename RanIter>
BOOST_CONCEPT_REQUIRES(
((Mutable_RandomAccessIterator<RanIter>))
((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)),
(void)) // 返回類型 stable_sort(RanIter,RanIter);
注意,該算法要求迭代器的值類型是 LessThanComparable 的,並且它通過
Mutable_RandomAccessIterator 概念檢查模板來訪問該值類型。通常,Boost 概念檢查類以嵌套的成員 typedefs 來表示相關類型,以便你可以使用這一語法,它模仿了下一個版本的C++中建議的概念支持的方法。
有些概念關聯了多個類型。這種情況下,相應的概念檢查類具有多個模板參數。以下例子示範了如何將 BOOST_CONCEPT_REQUIRES 用於 ReadWritePropertyMap 概念,它接受兩個類型參數:一個屬性映射和該映射的鍵類型。
template <class G, class Buffer, class BFSVisitor,
class ColorMap>
BOOST_CONCEPT_REQUIRES(
((ReadWritePropertyMap<ColorMap, typename IncidenceGraph<G>::vertex_descriptor>)),
(void)) // 返回類型 breadth_first_search(G& g, typename graph_traits<IncidenceGraph>::vertex_descriptor s, Buffer& Q, BFSVisitor vis, ColorMap color) { typedef typename IncidenceGraph<G>::vertex_descriptor Vertex; ... }
雖然概念檢查是為了實現泛型庫而設計的,但它們也可以用於最終用戶。有時,你不能確認某個類型是否符合某個特定概念。至少,語法上的要求可以很容易地通過創建一個小程序來並使用帶類型和概念的 BOOST_CONCEPT_ASSERT 來進行檢查。例如:
// 確認 list<int> 具有雙向迭代器 BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator>));
Prev: Concept Checking
Introduction 概念檢查簡介
Next: Creating Concept Checking
Classes 創建概念檢查類
| Copyright © 2000 | Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. |