0381c5fc54
Some documentation links currently point to pages that HP retired along with the rest of the SGI STL website. These links now point to the Boost mirror site.
158 lines
6.4 KiB
HTML
158 lines
6.4 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
|
|
<!-- 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) -->
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content=
|
|
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
|
|
|
|
<title>Creating Concept Checking Classes</title>
|
|
<link rel="stylesheet" href="../../rst.css" type="text/css" />
|
|
</head>
|
|
|
|
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
|
|
"#FF0000">
|
|
<img src="../../boost.png" alt="C++ Boost" width="277" height=
|
|
"86" /><br clear="none" />
|
|
|
|
<h2><a name="creating-concept-checks" id="creating-concept-checks">Creating
|
|
Concept Checking Classes</a></h2>
|
|
|
|
<p>As an example of how to create a concept checking class template, we
|
|
look at how to create the corresponding checks for the <a href=
|
|
"http://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a> concept.
|
|
The complete definition is here:</p>
|
|
<pre>
|
|
template <class X>
|
|
struct InputIterator
|
|
: Assignable<X>, EqualityComparable<X>
|
|
{
|
|
private:
|
|
typedef std::iterator_traits<X> t;
|
|
public:
|
|
typedef typename t::value_type value_type;
|
|
typedef typename t::difference_type difference_type;
|
|
typedef typename t::reference reference;
|
|
typedef typename t::pointer pointer;
|
|
typedef typename t::iterator_category iterator_category;
|
|
|
|
BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
|
|
BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
|
|
|
|
BOOST_CONCEPT_USAGE(InputIterator)
|
|
{
|
|
X j(i); <font color=
|
|
"green">// require copy construction</font>
|
|
same_type(*i++,v); <font color=
|
|
"green">// require postincrement-dereference returning value_type</font>
|
|
X& x = ++j; <font color=
|
|
"green">// require preincrement returning X&</font>
|
|
}
|
|
|
|
private:
|
|
X i;
|
|
value_type v;
|
|
|
|
<font color=
|
|
"green">// Type deduction will fail unless the arguments have the same type.</font>
|
|
template <typename T>
|
|
void same_type(T const&, T const&);
|
|
};
|
|
</pre>
|
|
|
|
<h3>Walkthrough</h3>
|
|
|
|
<p>First, as a convention we name the concept checking class after the
|
|
concept. Next, since InputIterator is a refinement of Assignable and
|
|
EqualityComparable, we derive its concept checking class from the checking
|
|
classes for those other concepts. The library will automatically check for
|
|
conformance to Assignable and EqualityComparable whenever it checks the
|
|
InputIterator concept.</p>
|
|
|
|
<p>Next, we declare the concept's <a href=
|
|
"http://www.boost.org/more/generic_programming.html#associated_type">associated types</a>
|
|
as member typedefs. The associated difference type is required to be a
|
|
signed integer, and the iterator category has to be convertible to
|
|
std::input_iterator_tag, so we assert those relationships. The syntax for
|
|
accessing associated types through the concept-checking template mirrors
|
|
the <a href=
|
|
"http://www.generic-programming.org/languages/conceptcpp/">proposed</a>
|
|
syntax for associated type access in C++0x Finally, we use the
|
|
<code>BOOST_CONCEPT_USAGE</code> macro to declare the function that
|
|
exercises all the concept's valid expressions. Note that at this point you
|
|
may sometimes need to be a little creative: for example, to check that
|
|
<code>*i++</code> returns the iterator's value type, we pass both values to
|
|
the <code>same_type</code> member function template, which requires both
|
|
arguments to have the same type, modulo references and cv-qualification.
|
|
It's an imperfect check, but it's better than nothing.</p>
|
|
|
|
<h3>Values for Usage Patterns Should Be Data Members</h3>
|
|
|
|
<p>You may be wondering why we declared <code>i</code> and <code>v</code>
|
|
as data members in the example above. Why didn't we simply write the
|
|
following?</p>
|
|
<pre>
|
|
BOOST_CONCEPT_USAGE(InputIterator)
|
|
{
|
|
X i; <font color=
|
|
"green">// create the values we need</font>
|
|
value_type v;
|
|
|
|
X j(i); <font color=
|
|
"green">// require copy construction</font>
|
|
same_type(*i++,v); <font color=
|
|
"green">// require postincrement-dereference returning value_type</font>
|
|
X& x = ++j; <font color=
|
|
"green">// require preincrement returning X&</font>
|
|
}
|
|
</pre>
|
|
|
|
<p>Unfortunately, that code wouldn't have worked out so well, because it
|
|
unintentionally imposes the requirement that <code>X</code> and its value
|
|
type are both default-constructible. On the other hand, since instances of
|
|
the <code>InputIterator</code> template will never be constructed, the
|
|
compiler never has to check how its data members will be constructed (C++
|
|
Standard Section 14.7.1 9). For that reason you should <strong>always
|
|
declare values needed for usage patterns as data members</strong>.</p>
|
|
|
|
<p>These sorts of errors in concept definitions can be detected by the use
|
|
of <a href="concept_covering.htm">Concept Archetypes</a>, but it's always
|
|
better to avoid them pre-emptively.</p>
|
|
|
|
<h3>Similarity to Proposed C++0x Language Support for Concepts</h3>
|
|
|
|
<p>This library's syntaxes for concept refinement and for access of
|
|
associated types mirrors the corresponding <a href=
|
|
"http://www.generic-programming.org/languages/conceptcpp/">proposed</a>
|
|
syntaxes in C++0x. However, C++0x will use
|
|
“signatures” rather than usage patterns to
|
|
describe the valid operations on types participating in a concept, so when
|
|
converting your concept checking classes into language-supported concepts,
|
|
you'll need to translate your usage function into a series of
|
|
signatures.</p>
|
|
|
|
<p><a href="./concept_covering.htm">Next: Concept Covering and
|
|
Archetypes</a><br />
|
|
<a href="./using_concept_check.htm">Prev: Using Concept
|
|
Checks</a><br /></p>
|
|
<hr />
|
|
|
|
<table>
|
|
<tr valign="top">
|
|
<td nowrap="nowrap">Copyright © 2000</td>
|
|
|
|
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
|
|
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
|
|
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
|
|
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
|
|
</tr>
|
|
</table>
|
|
</body>
|
|
</html>
|