📄 iterator_tags.html
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Zafir Anjum">
<TITLE>MFC Programmer's SourceBook : STL Programmer's Guide</TITLE>
<META name="description"
content="A freely available implementation
of the C++ Standard Template Library, including
hypertext documentation.">
<META name="keywords"
content="generic programming, STL, standard template library">
</HEAD>
<SCRIPT LANGUAGE="JavaScript"><!--
var adcategory = "cpp";
// -->
</SCRIPT>
<body background="../../fancyhome/back.gif" bgcolor="#FFFFFF" >
<SCRIPT LANGUAGE="JavaScript"><!--
var nfrm = location.href.indexOf("_nfrm_");
var validframes = (top.frames.length > 0 && top.frames['ad'] && top.frames['logo'] );
var random = Math.random();
if( !validframes && nfrm == -1 )
{
var dclkPage = "www.codeguru.com/";
if( self.adcategory )
dclkPage += adcategory;
else
dclkPage += "mfc";
document.write('<nolayer><center>');
document.write('<iframe src="http://ad.doubleclick.net/adi/' + dclkPage + ';ord='
+ random + '" width=470 height=62 marginwidth=0 marginheight=0 hspace=0 vspace=0 '
+ 'frameborder=0 scrolling=no bordercolor="#000000">');
document.write('<a href="http://ad.doubleclick.net/jump/' + dclkPage + ';ord='
+ random + '">');
document.write('<img src="http://ad.doubleclick.net/ad/' + dclkPage + ';ord='
+ random + '" height=60 width=468>' + '</a>');
document.write('</iframe>');
document.write('</center></nolayer>');
document.write('<layer src="http://ad.doubleclick.net/adl/' + dclkPage +
';ord=' + random + '"></layer>');
document.write('<ilayer visibility=hide width=468 height=83></ilayer>');
}
// top.location = "/show.cgi?" + adcategory + "=" + location.pathname;
// -->
</SCRIPT>
<noscript>
<p align="center">
<a href="http://ad.doubleclick.net/jump/www.codeguru.com/cpp;ord=NupaitFCY34AAHUFAmY">
<img src="http://ad.doubleclick.net/ad/www.codeguru.com/cpp;ord=NupaitFCY34AAHUFAmY"></a>
</p>
</noscript>
<BR Clear>
<H1>Iterator Tags</H1>
<Table CellPadding=0 CellSpacing=0 width=100%>
<TR>
<TD Align=left><Img src = "iterators.gif" Alt="" WIDTH = "194" HEIGHT = "38" ></TD>
<TD Align=right><Img src = "overview.gif" Alt="" WIDTH = "194" HEIGHT = "38" ></TD>
</TR>
<TR>
<TD Align=left VAlign=top><b>Category</b>: iterators</TD>
<TD Align=right VAlign=top><b>Component type</b>: overview</TD>
</TR>
</Table>
<h3>Summary</h3>
Iterator tag functions are a method for accessing information that is
associated with iterators. Specifically, an iterator type must, as
discussed in the <A href="InputIterator.html">Input Iterator</A> requirements, have an
associated <i>distance type</i> and <i>value type</i>. <A href="#1">[1]</A> It is sometimes
important for an algorithm parameterized by an iterator type to be
able to determine the distance type and value type. Iterator tags
also allow algorithms to determine an iterator's category, so that
they can take different actions depending on whether an iterator is an
<A href="InputIterator.html">Input Iterator</A>, <A href="OutputIterator.html" tppabs="http://www.sgi.com/Technology/STL/OutputIterator.shtml">Output Iterator</A>, <A href="ForwardIterator.html" tppabs="http://www.sgi.com/Technology/STL/ForwardIterator.shtml">Forward Iterator</A>,
<A href="BidirectionalIterator.html">Bidirectional Iterator</A>, or <A href="RandomAccessIterator.html" tppabs="http://www.sgi.com/Technology/STL/RandomAccessIterator.shtml">Random Access Iterator</A>.
<P>
Note that the iterator tag functions <tt><A href="distance_type.html">distance_type</A></tt>,
<tt><A href="value_type.html">value_type</A></tt>, and <tt><A href="iterator_category.html" tppabs="http://www.sgi.com/Technology/STL/iterator_category.shtml">iterator_category</A></tt> are an older method of
accessing the type information associated with iterators: they were
defined in the original STL. The draft C++ standard, however, defines
a different and more convenient mechanism: <tt><A href="iterator_traits.html">iterator_traits</A></tt>.
Both mechanisms are supported <A href="#2">[2]</A>, for reasons of backwards
compatibility, but the older mechanism will eventually be
removed.
<h3>Description</h3>
The basic idea of the iterator tag functions, and of
<tt><A href="iterator_traits.html">iterator_traits</A></tt>, is quite simple: iterators have associated type
information, and there must be a way to access that information.
Specifically, iterator tag functions and <tt><A href="iterator_traits.html">iterator_traits</A></tt> are
used to determine an iterator's value type, distance type, and
iterator category.
<P>
An iterator's <i>category</i> is the most specific concept that it is a
model of: <A href="InputIterator.html">Input Iterator</A>, <A href="OutputIterator.html" tppabs="http://www.sgi.com/Technology/STL/OutputIterator.shtml">Output Iterator</A>, <A href="ForwardIterator.html" tppabs="http://www.sgi.com/Technology/STL/ForwardIterator.shtml">Forward Iterator</A>,
<A href="BidirectionalIterator.html">Bidirectional Iterator</A>, or <A href="RandomAccessIterator.html" tppabs="http://www.sgi.com/Technology/STL/RandomAccessIterator.shtml">Random Access Iterator</A>.
This information is expressed in the C++ type system by defining five
category tag types, <tt><A href="input_iterator_tag.html">input_iterator_tag</A></tt>,
<tt><A href="output_iterator_tag.html">output_iterator_tag</A></tt>, <tt><A href="forward_iterator_tag.html" tppabs="http://www.sgi.com/Technology/STL/forward_iterator_tag.shtml">forward_iterator_tag</A></tt>,
<tt><A href="bidirectional_iterator_tag.html">bidirectional_iterator_tag</A></tt>, and
<tt><A href="random_access_iterator_tag.html">random_access_iterator_tag</A></tt>, each of which corresponds to one of
those concepts. <A href="#3">[3]</A>
<P>
The function <tt><A href="iterator_category.html">iterator_category</A></tt> takes a single argument, an
iterator, and returns the tag corresponding to that iterator's
category. That is, it returns a <tt><A href="random_access_iterator_tag.html">random_access_iterator_tag</A></tt> if
its argument is a pointer, a <tt><A href="bidirectional_iterator_tag.html">bidirectional_iterator_tag</A></tt> if its
argument is a <tt><A href="List.html">list</A>::iterator</tt>, and so on. <tt>Iterator_traits</tt>
provides the same information in a slightly different way: if <tt>I</tt> is
an iterator, then <tt><A href="iterator_traits.html">iterator_traits</A><I>::iterator_category</tt> is a nested
<tt>typedef</tt>: it is one of the five category tag types.
<P>
An iterator's <i>value type</i> is the type of object that is returned
when the iterator is dereferenced. (See the discussion in the
<A href="InputIterator.html">Input Iterator</A> requirements.) Ideally, one might want
<tt><A href="value_type.html">value_type</A></tt> to take a single argument, an iterator, and return
the iterator's value type. Unfortunately, that's impossible:
a function must return an object, and types aren't objects. Instead,
<tt><A href="value_type.html">value_type</A></tt> returns the value <tt>(T*) 0</tt>, where <tt>T</tt> is the
argument's value type. The <tt>iterator_traits</tt> class, however,
does not have this restriction: <tt>iterator_traits<I>::value_type</tt>
is a type, not a value. It is a nested <tt>typedef</tt>, and it can be
used in declarations of variables, as an function's argument type or
return type, and in any other ways that C++ types can be used.
<P>
(Note that the function <tt><A href="value_type.html">value_type</A></tt> need
not be defined for <A href="OutputIterator.html">Output Iterators</A>, since an <A href="OutputIterator.html" tppabs="http://www.sgi.com/Technology/STL/OutputIterator.shtml">Output Iterator</A>
need not have a value type. Similarly, <tt><A href="iterator_traits.html">iterator_traits</A><I>::value_type</tt>
is typically defined as <tt>void</tt> when <tt>I</tt> is an output iterator)
<P>
An iterator's <i>distance type</i>, or <i>difference type</i> (the terms
are synonymous) is the type that is used to represent the distance
between two iterators. (See the discussion in the <A href="InputIterator.html">Input Iterator</A>
requirements.) The function <tt><A href="distance_type.html">distance_type</A></tt> returns this
information in the same form that <tt><A href="value_type.html">value_type</A></tt> does: its argument
is an iterator, and it returns the value <tt>(Distance*) 0</tt>, where
<tt>Distance</tt> is the iterator's distance type. Similarly,
<tt><A href="iterator_traits.html">iterator_traits</A><I>::difference_type</tt> is <tt>I</tt>'s distance type.
<P>
Just as with <tt><A href="value_type.html">value_type</A></tt>, the function <tt><A href="distance_type.html" tppabs="http://www.sgi.com/Technology/STL/distance_type.shtml">distance_type</A></tt> need
not be defined for <A href="OutputIterator.html">Output Iterators</A>, and, if <tt>I</tt> is an
<A href="OutputIterator.html">Output Iterator</A>, <tt><A href="iterator_traits.html" tppabs="http://www.sgi.com/Technology/STL/iterator_traits.shtml">iterator_traits</A><I>::difference_type</tt>
may be defined as <tt>void</tt>. An <A href="OutputIterator.html">Output Iterator</A>
need not have a distance type.
<P>
The functions <tt><A href="iterator_category.html">iterator_category</A></tt>, <tt><A href="value_type.html" tppabs="http://www.sgi.com/Technology/STL/value_type.shtml">value_type</A></tt>, and
<tt><A href="distance_type.html">distance_type</A></tt> must be provided for every type of iterator.
(Except, as noted above, that <tt><A href="value_type.html">value_type</A></tt> and <tt><A href="distance_type.html" tppabs="http://www.sgi.com/Technology/STL/distance_type.shtml">distance_type</A></tt>
need not be provided for <A href="OutputIterator.html">Output Iterators</A>.) In principle, this is
simply a matter of overloading: anyone who defines a new iterator type
must define those three functions for it. In practice, there's a
slightly more convenient method. The STL defines five base classes,
<tt><A href="output_iterator.html">output_iterator</A></tt>, <tt><A href="input_iterator.html" tppabs="http://www.sgi.com/Technology/STL/input_iterator.shtml">input_iterator</A></tt>, <tt><A href="forward_iterator.html" tppabs="http://www.sgi.com/Technology/STL/forward_iterator.shtml">forward_iterator</A></tt>,
<tt><A href="bidirectional_iterator.html">bidirectional_iterator</A></tt>, and <tt><A href="random_access_iterator.html" tppabs="http://www.sgi.com/Technology/STL/random_access_iterator.shtml">random_access_iterator</A></tt>. The
functions <tt><A href="iterator_category.html">iterator_category</A></tt>, <tt><A href="value_type.html" tppabs="http://www.sgi.com/Technology/STL/value_type.shtml">value_type</A></tt>, and
<tt><A href="distance_type.html">distance_type</A></tt> are defined for those base classes. The effect,
then, is that if you are defining a new type of iterator you can
simply derive it from one of those base classes, and the iterator tag
functions will automatically be defined correctly. These base classes
contain no member functions or member variables, so deriving from one
of them ought not to incur any overhead.
<P>
(Again, note that base classes are provided solely for the
convenience of people who define iterators. If you define a class
<tt>Iter</tt> that is a new kind of <A href="BidirectionalIterator.html">Bidirectional Iterator</A>, you do not
have to derive it from the base class <tt><A href="bidirectional_iterator.html">bidirectional_iterator</A></tt>. You
do, however, have to make sure that <tt><A href="iterator_category.html">iterator_category</A></tt>,
<tt><A href="value_type.html">value_type</A></tt>, and <tt><A href="distance_type.html" tppabs="http://www.sgi.com/Technology/STL/distance_type.shtml">distance_type</A></tt> are defined correctly for
arguments of type <tt>Iter</tt>, and deriving <tt>Iter</tt> from
<tt><A href="bidirectional_iterator.html">bidirectional_iterator</A></tt> is usually the most convenient way to do
that.)
<h3>Examples</h3>
This example uses the <tt><A href="value_type.html">value_type</A></tt> iterator tag function in order
to declare a temporary variable of an iterator's value type. Note the
use of an auxiliary function, <tt>__iter_swap</tt>. This is a very common
idiom: most uses of iterator tags involve auxiliary functions.
<pre>
template <class <A href="ForwardIterator.html">ForwardIterator</A>1, class <A href="ForwardIterator.html" tppabs="http://www.sgi.com/Technology/STL/ForwardIterator.shtml">ForwardIterator</A>2, class ValueType>
inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, ValueType*) {
T tmp = *a;
*a = *b;
*b = tmp;
}
template <class <A href="ForwardIterator.html">ForwardIterator</A>1, class <A href="ForwardIterator.html" tppabs="http://www.sgi.com/Technology/STL/ForwardIterator.shtml">ForwardIterator</A>2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
__iter_swap(a, b, <A href="value_type.html">value_type</A>(a));
}
</pre>
<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -