mirror of
https://github.com/boostorg/concept_check.git
synced 2026-02-22 18:14:59 +01:00
149 lines
6.2 KiB
HTML
149 lines
6.2 KiB
HTML
<HTML>
|
|
<!--
|
|
-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000
|
|
--
|
|
-- Permission to use, copy, modify, distribute and sell this software
|
|
-- and its documentation for any purpose is hereby granted without fee,
|
|
-- provided that the above copyright notice appears in all copies and
|
|
-- that both that copyright notice and this permission notice appear
|
|
-- in supporting documentation. We make no
|
|
-- representations about the suitability of this software for any
|
|
-- purpose. It is provided "as is" without express or implied warranty.
|
|
-->
|
|
<Head>
|
|
<Title>Programming With Concepts</Title>
|
|
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
|
ALINK="#ff0000">
|
|
<IMG SRC="../../c++boost.gif"
|
|
ALT="C++ Boost" width="277" height="86">
|
|
|
|
<BR Clear>
|
|
|
|
<h2><a name="programming-with-concepts">Programming with Concepts</a></h2>
|
|
|
|
The process of deciding how to group requirements into concepts and
|
|
deciding which concepts to use in each algorithm is perhaps the most
|
|
difficult (yet most important) part of building a generic library.
|
|
A guiding principle to use during this process is one we
|
|
call the <i>requirement minimization principle</i>.
|
|
|
|
<p>
|
|
<b>Requirement Minimization Principle:</b> Minimize the requirements
|
|
on the input parameters of a component to increase its reusability.
|
|
|
|
<p>
|
|
There is natural tension in this statement. By definition, the input
|
|
parameters must be used by the component in order for the component to
|
|
accomplish its task (by ``component'' we mean a function or class
|
|
template). The challenge then is to implement the component in such a
|
|
way that makes the fewest assumptions (the minimum requirements) about
|
|
the inputs while still accomplishing the task.
|
|
|
|
<p>
|
|
The traditional notions of <i>abstraction</i> tie in directly to the
|
|
idea of minimal requirements. The more abstract the input, the fewer
|
|
the requirements. Thus, concepts are simply the embodiment of generic
|
|
abstract data types in C++ template programming.
|
|
|
|
<p>
|
|
When designing the concepts for some problem domain it is important to
|
|
keep in mind their purpose, namely to express the requirements for the
|
|
input to the components. With respect to the requirement minimization
|
|
principle, this means we want to minimize concepts.
|
|
|
|
<!-- the following discussion does not match the Standard definition
|
|
of LessThanComparable and needs to be changed -Jeremy
|
|
|
|
<p>
|
|
It is important to note, however, that
|
|
minimizing concepts does not mean simply
|
|
reducing the number of valid expressions
|
|
in the concept.
|
|
For example, the
|
|
<tt>std::stable_sort()</tt> function requires that the value type of
|
|
the iterator be <a
|
|
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a>, which not only
|
|
includes <tt>operator<()</tt>, but also <tt>operator>()</tt>,
|
|
<tt>operator<=()</tt>, and <tt>operator>=()</tt>.
|
|
It turns out that <tt>std::stable_sort()</tt> only uses
|
|
<tt>operator<()</tt>. The question then arises: should
|
|
<tt>std::stable_sort()</tt> be specified in terms of the concept
|
|
<a
|
|
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a> or in terms of a concept that only
|
|
requires <tt>operator<()</tt>?
|
|
|
|
<p>
|
|
We remark first that the use of <a
|
|
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a> does not really violate the requirement
|
|
minimization principle because all of the other operators can be
|
|
trivially implemented in terms of <tt>operator<()</tt>. By
|
|
``trivial'' we mean one line of code and a constant run-time cost.
|
|
More fundamentally, however, the use of <a
|
|
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a> does not violate the requirement minimization
|
|
principle because all of the comparison operators (<tt><</tt>,
|
|
<tt>></tt>, <tt><=</tt>, <tt>>=</tt>) are conceptually equivalent (in
|
|
a mathematical sense). Adding conceptually equivalent valid
|
|
expressions is not a violation of the requirement minimization
|
|
principle because no new semantics are being added --- only new
|
|
syntax. The added syntax increases re-usability.
|
|
|
|
<p>
|
|
For example,
|
|
the
|
|
maintainer of the <tt>std::stable_sort()</tt> may some day change the
|
|
implementation in places to use <tt>operator>()</tt> instead of
|
|
<tt>operator<()</tt>, since, after all, they are equivalent. Since the
|
|
requirements are part of the public interface, such a change could
|
|
potentially break client code. If instead
|
|
<a
|
|
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a> is given as the requirement for
|
|
<tt>std::stable_sort()</tt>, then the maintainer is given a reasonable
|
|
amount of flexibility within which to work.
|
|
|
|
-->
|
|
|
|
<p>
|
|
Minimality in concepts is a property associated with the underlying
|
|
semantics of the problem domain being represented. In the problem
|
|
domain of basic containers, requiring traversal in a single direction
|
|
is a smaller requirement than requiring traversal in both directions
|
|
(hence the distinction between <a
|
|
href="http://www.sgi.com/Technology/STL/ForwardIterator.html">
|
|
ForwardIterator</a> and
|
|
<a
|
|
href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">
|
|
BidirectionalIterator</a>). The semantic difference can be easily seen
|
|
in the difference between the set of concrete data structures that
|
|
have forward iterators versus the set that has bidirectional
|
|
iterators. For example, singly-linked lists would fall in the set of
|
|
data structures having forward iterators, but not bidirectional
|
|
iterators. In addition, the set of algorithms that one can implement
|
|
using only forward iterators is quite different than the set that can
|
|
be implemented with bidirectional iterators. Because of this, it is
|
|
important to factor families of requirements into rather fine-grained
|
|
concepts. For example, the requirements for iterators are factored
|
|
into the six STL iterator concepts (trivial, output, input, forward,
|
|
bidirectional, and random access).
|
|
|
|
<p>
|
|
<a href="./implementation.htm">Next: Implementation</a><br>
|
|
<a href="./concept_covering.htm">Prev: Concept Covering and Archetypes</a>
|
|
|
|
<br>
|
|
<HR>
|
|
<TABLE>
|
|
<TR valign=top>
|
|
<TD nowrap>Copyright © 2000</TD><TD>
|
|
<A HREF="../../people/jeremy_siek.htm">Jeremy Siek</A>,
|
|
Univ.of Notre Dame (<A
|
|
HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
|
|
</TD></TR></TABLE>
|
|
|
|
</BODY>
|
|
</HTML>
|