containers_and_c.html revision 1.1.1.1.2.1
1<?xml version="1.0" encoding="UTF-8" standalone="no"?> 2<!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"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Interacting with C</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.78.1" /><meta name="keywords" content="ISO C++, library" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="../index.html" title="The GNU C++ Library" /><link rel="up" href="containers.html" title="Chapter��9.�� Containers" /><link rel="prev" href="unordered_associative.html" title="Unordered Associative" /><link rel="next" href="iterators.html" title="Chapter��10.�� Iterators" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Interacting with C</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="unordered_associative.html">Prev</a>��</td><th width="60%" align="center">Chapter��9.�� 3 Containers 4 5</th><td width="20%" align="right">��<a accesskey="n" href="iterators.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.containers.c"></a>Interacting with C</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="containers.c.vs_array"></a>Containers vs. Arrays</h3></div></div></div><p> 6 You're writing some code and can't decide whether to use builtin 7 arrays or some kind of container. There are compelling reasons 8 to use one of the container classes, but you're afraid that 9 you'll eventually run into difficulties, change everything back 10 to arrays, and then have to change all the code that uses those 11 data types to keep up with the change. 12 </p><p> 13 If your code makes use of the standard algorithms, this isn't as 14 scary as it sounds. The algorithms don't know, nor care, about 15 the kind of <span class="quote">���<span class="quote">container</span>���</span> on which they work, since 16 the algorithms are only given endpoints to work with. For the 17 container classes, these are iterators (usually 18 <code class="code">begin()</code> and <code class="code">end()</code>, but not always). 19 For builtin arrays, these are the address of the first element 20 and the <a class="link" href="iterators.html#iterators.predefined.end" title="One Past the End">past-the-end</a> element. 21 </p><p> 22 Some very simple wrapper functions can hide all of that from the 23 rest of the code. For example, a pair of functions called 24 <code class="code">beginof</code> can be written, one that takes an array, 25 another that takes a vector. The first returns a pointer to the 26 first element, and the second returns the vector's 27 <code class="code">begin()</code> iterator. 28 </p><p> 29 The functions should be made template functions, and should also 30 be declared inline. As pointed out in the comments in the code 31 below, this can lead to <code class="code">beginof</code> being optimized out 32 of existence, so you pay absolutely nothing in terms of increased 33 code size or execution time. 34 </p><p> 35 The result is that if all your algorithm calls look like 36 </p><pre class="programlisting"> 37 std::transform(beginof(foo), endof(foo), beginof(foo), SomeFunction); 38 </pre><p> 39 then the type of foo can change from an array of ints to a vector 40 of ints to a deque of ints and back again, without ever changing 41 any client code. 42 </p><pre class="programlisting"> 43// beginof 44template<typename T> 45 inline typename vector<T>::iterator 46 beginof(vector<T> &v) 47 { return v.begin(); } 48 49template<typename T, unsigned int sz> 50 inline T* 51 beginof(T (&array)[sz]) { return array; } 52 53// endof 54template<typename T> 55 inline typename vector<T>::iterator 56 endof(vector<T> &v) 57 { return v.end(); } 58 59template<typename T, unsigned int sz> 60 inline T* 61 endof(T (&array)[sz]) { return array + sz; } 62 63// lengthof 64template<typename T> 65 inline typename vector<T>::size_type 66 lengthof(vector<T> &v) 67 { return v.size(); } 68 69template<typename T, unsigned int sz> 70 inline unsigned int 71 lengthof(T (&)[sz]) { return sz; } 72</pre><p> 73 Astute readers will notice two things at once: first, that the 74 container class is still a <code class="code">vector<T></code> instead 75 of a more general <code class="code">Container<T></code>. This would 76 mean that three functions for <code class="code">deque</code> would have to be 77 added, another three for <code class="code">list</code>, and so on. This is 78 due to problems with getting template resolution correct; I find 79 it easier just to give the extra three lines and avoid confusion. 80 </p><p> 81 Second, the line 82 </p><pre class="programlisting"> 83 inline unsigned int lengthof (T (&)[sz]) { return sz; } 84 </pre><p> 85 looks just weird! Hint: unused parameters can be left nameless. 86 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="unordered_associative.html">Prev</a>��</td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right">��<a accesskey="n" href="iterators.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Unordered Associative��</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top">��Chapter��10.�� 87 Iterators 88 89</td></tr></table></div></body></html>