对于每个概念,都有一个概念检查类模板,可用于确保给定的类型(或一组类型)符合该概念。Boost 概念检查库 (BCCL) 包含了 C++ 标准库所使用的所有概念以及其他一些概念的检查类模板。请参阅 参考 部分以获取完整列表。此外,其他 Boost 库也附带了特定于这些库的概念的检查类。例如,有 图概念 (graph concepts) 和 属性映射概念 (property map concepts)。同样,每当**任何人**在编写函数模板时需要表达现有概念尚未涵盖的需求时,都应创建一个新的概念检查类。如何执行此操作在 创建概念检查类 中有说明。
BCCL 中概念检查类的一个示例是EqualityComparable类。该类对应于 C++ 标准 20.1.1 节中描述的 EqualityComparable(相等可比较)要求,以及 SGI STL 中记录的 EqualityComparable 概念。
template <class T> struct EqualityComparable;
模板参数是要检查的类型。也就是说,EqualityComparable<T>的目的在于确保T符合 EqualityComparable 概念。
检查概念需求最通用的方法是使用 BOOST_CONCEPT_ASSERT() 宏。您可以在任何作用域中使用此宏,只需传入括在括号中的概念检查模板特化即可。注意:这意味着调用 BOOST_CONCEPT_ASSERT 时看起来会使用双重括号。
// In my library:
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>));
// ...
};
// In the user's code:
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 <class RanIter>
BOOST_CONCEPT_REQUIRES(
((Mutable_RandomAccessIterator<RanIter>))
((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)),
(void)) // return type
stable_sort(RanIter,RanIter);
请注意,该算法要求迭代器的值类型必须是 LessThanComparable(小于可比较的),并且它通过 Mutable_RandomAccessIterator 概念检查模板访问该值类型。通常,Boost 概念检查类将关联类型公开为嵌套的成员 typedef,以便您可以使用此语法,这模仿了为下一版本 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)) // return type
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处理相关类型和概念,可以轻松检查语法要求。例如
// Make sure list<int> has bidirectional iterators. BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator>));
| 版权 © 2000 | Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. |