Using Concept ChecksFor each concept there is a concept checking class template that can be used to make sure that a given type (or set of types) models the concept. The Boost Concept Checking Library (BCCL) includes concept checking class templates for all of the concepts used in the C++ standard library and a few more. See the Reference section for a complete list. In addition, other boost libraries come with concept checking classes for the concepts that are particular to those libraries. For example, there are graph concepts and property map concepts. Also, whenever anyone writing function templates needs to express requirements that are not yet stated by an existing concept, a new concept checking class should be created. How to do this is explained in Creating Concept Checking Classes. An example of a concept checking class from the BCCL is the EqualityComparableConcept class. The class corresponds to the EqualityComparable requirements described in 20.1.1 of the C++ Standard, and to the EqualityComparable concept documented in the SGI STL. template <class T> struct EqualityComparable; The template argument is the type to be checked. That is, the purpose of EqualityComparable<X> is to make sure that X models the EqualityComparable concept. BOOST_CONCEPT_ASSERT()The most versatile way of checking concept requirements is to use the
// 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; //... } BOOST_CONCEPT_REQUIRESOne of the nice things about the proposed C++0x syntax
for declaring concept constrained function templates is the way that
constraints are part of the function declaration, so clients will
see them. The BOOST_CONCEPT_REQUIRES macro can be used in a function
template declaration to check whether some type models a concept. It
accepts two arguments, a list of constraints, and the
function template's return type. The list of constraints takes the form of
a sequence of adjacent concept checking template specializations,
in double parentheses, and the function's return type must
also be parenthesized. For example, the standard template<typename RanIter> BOOST_CONCEPT_REQUIRES( ((Mutable_RandomAccessIterator<RanIter>)) ((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)), (void)) // return type stable_sort(RanIter,RanIter); Note that the algorithm requires that the value type of the iterator be
LessThanComparable, and it accesses that value type through the
Multi-Type ConceptsSome concepts deal with more than one type. In this case the corresponding concept checking class will have multiple template parameters. The following example shows how BOOST_CONCEPT_REQUIRES is used with the ReadWritePropertyMap concept, which takes two type parameters: a property map and the key type for the map. 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; ... } Although concept checks are designed for use by generic library implementors, they can also be useful to end users. Sometimes one may not be sure whether some type models a particular concept. The syntactic requirements, at least, can easily be checked by creating a small program and using BOOST_CONCEPT_ASSERT with the type and concept in question. For example: // Make sure list<int> has bidirectional iterators. BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator>)); Prev: Concept Checking
Introduction
|