    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: C++ Idioms: First Thoughts</title>
        <link>https://members.accu.org/index.php/articles/451</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #42 - Apr 2001</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c162/">42</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-162/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+162/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;C++ Idioms: First Thoughts</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 April 2001 17:46:05 +01:00 or Thu, 26 April 2001 17:46:05 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>One of the major problems with developing C++ skills is that
there is very little material available for those that have just
completed their introduction to the language. There are numerous
books that purport to introduce you to C++ and a very few do a good
job of it. There are quite a few books that will help develop the
skills of those that have thoroughly mastered the language. There
are also a handful of books that highlight particular details.
However I do not know of any that focus on the modern idioms of the
language. My intention in this article is to cover a number of
things that I think are useful and to invite readers to both
critique my ideas and to add material of their own.</p>
<p>Experts among the readership will probably be familiar with many
of the items in this article, and may have ideas as to how they may
be better developed. If you are among those, please at least skim
this article because I will start with some very simple things but
I will, hopefully, progress to more complicated ones.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e24" id="d0e24"></a>Largely Lexical
Idioms</h2>
</div>
<p>The ideas I will present in this section are almost entirely to
do with how you present your code. I do not mean such trivia as
white-space conventions and where you place your braces; I hope the
following will be a little more significant.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e29" id="d0e29"></a>1) Prefer 'Need to
Know Ordering'</h3>
</div>
<p>When you have options as to how you write code, think carefully
about what the user needs to know. For example, the most important
thing for most users of a class is the public interface. Therefore
make sure that it is easily and quickly visible on the screen.
Organise class definitions so that the public interface comes first
and the private interface last. If for no other reason, question
in-class definitions of member functions. If you decide that a
member function should be inline, define it after the class
definition. Actually, seriously consider placing inline definitions
in their own file that can be included into the header file when
the code is stable enough to pay the price of forcing such a
dependency on the user of the class.</p>
<p>The principle of 'need to know ordering' should permeate your
coding style. Do not dump information onto your fellow programmer.
Some time ago Jon Jagger suggested that file scope comments should
be organised on this basis. When a user looks at a header file they
are most likely to want to know about the class definitions and
function declarations in the file, and are much less likely to want
to know the development history. In general, file scope comments
should be later rather than earlier in a file. By all means start
with a comment that claims copyright and gives a release date but
that would normally be sufficient.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e36" id="d0e36"></a>2) Be
Consistent</h3>
</div>
<p>When presented with choices that only apply sometimes, be
consistent.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e41" id="d0e41"></a>a) Placement of
const</h4>
</div>
<p><tt class="literal">const</tt> normally qualifies the type
directly to its left. There is a special case when there is no type
to the left, in which case it qualifies the type name directly to
its right. Note that I carefully chose 'type name' in that last
sentence; if you use a <tt class="literal">typedef</tt> then a
leading const is equivalent to a <tt class="literal">const</tt>
immediately after the <tt class="literal">typedef</tt> name. The
following should clarify that:</p>
<pre class="programlisting">
typedef int * int_ptr;
const int_ptr * ipp; 
</pre>
<p>that last declaration is equivalent to:</p>
<pre class="programlisting">
int_ptr const * ipp;
</pre>
<p>which in turn is equivalent to:</p>
<pre class="programlisting">
int * const * ipp;
</pre>
<p>Note that that is not equivalent to 'const int * * ipp;'</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e69" id="d0e69"></a>b) struct or
class</h4>
</div>
<p>We know that either keyword will do in the context of
declaring/defining a user-defined type. Furthermore, in view of my
earlier advice (re need-to-know ordering), you will write exactly
(word for word) the same definition regardless of which choice you
make. My advice would be to consistently use 'class' unless you are
electing to have public data. In that case, always use '<tt class=
"literal">struct</tt>.' By the way, never have protected data.
Either data should be strictly part of the implementation and
inaccessible outside the context of that class or it should be
public because you have carefully considered the issue and
determined that public data is appropriate. A common case of this
is when you provide a private nested type. In such circumstances it
makes little sense to grant friendship to the enclosing class when
making the data public has the same effect.</p>
<p>While I am on this subject, note that strictly according to the
current standard it is not possible for an enclosing class to grant
friendship to a nested class (the most likely, and highly popular
among the Standards Committee, fix to this problem is to
automatically grant access to a nested scope/class. My next
suggestion is in that context). If you want to keep two blocks of
data and functions apart from each other, place each in its own
nested class, grant friendship to the enclosing class if
appropriate to your design.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e79" id="d0e79"></a>c) class and
typename</h4>
</div>
<p>In the context of template type parameters these two keywords
are equivalent. That does not mean that we should use them that
way. Some template type parameters can be built-in types (for
example, the type of the object that a <tt class=
"classname">vector</tt> contains), other template type parameters
must be a user defined type (for example, the STL <tt class=
"classname">priority_queue</tt> adaptor's second parameter). Either
consistently use just one of the keywords everywhere, or use
<tt class="literal">typename</tt> when built-in types are
possibilities but use class when they are not. Do not randomly
choose according to your current mood.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e93" id="d0e93"></a>d) Writing a
for-loop</h4>
</div>
<p>Strictly speaking this one is not a lexical convention because
the alternatives actually have different semantics. What I am
thinking of is how you should write a for-statement. Those of us
who first learnt C (particularly those with the wisdom to have read
and digested 'C Traps and Pitfalls' by Andy Koenig) will be used to
this idiom:</p>
<pre class="programlisting">
for (iter=0; iter&lt;max; iter++) { ... }
</pre>
<p>That makes perfectly good sense in C where <tt class=
"varname">iter</tt> is almost certainly some type of integer. It
still works fine in C++ when <tt class="varname">iter</tt> is an
integer type. However, in C++, <tt class="varname">iter</tt> is
highly likely to be some kind of user-defined iterator. This leads
to two changes.</p>
<p>We replace the '&lt;' with !=. That change is essential because
there is no guarantee that incrementing iterators will result in a
value that is greater than the previous one. Puzzled? Think about
how lists work. As we iterate through a list we get the address of
the next node, but there is no reason to suppose that this is
physically after the previous one, indeed, by the time we have
sorted out list, it probably isn't.</p>
<p>The second thing we do, for efficiency rather than correctness
this time, is to get a habit of using pre-increment/decrement
whenever we can. The pre versions are always at least as efficient
as the post versions but in the case of user defined types they are
usually much faster (indeed, originally C++ did not support
user-defined post increment/decrement).</p>
<p>So an experienced C++ programmer instinctively writes:</p>
<pre class="programlisting">
for (iter=0; iter!=max; ++iter) { ... }
</pre>
<p>Actually, the most common form for iteration looks like:</p>
<pre class="programlisting">
for (iterator iter=x.begin(); iter!=x.end(); ++iter) { ... }
</pre>
<p>and remarkably often that is rewritten as:</p>
<pre class="programlisting">
for_each(x.begin(), x.end(), dosomething)
</pre>
<p>which focuses the attention on the fact that you do the same
thing to every member of a container. Breaking old habits and using
newer idioms often makes your code clearer and therefore needing
fewer comments. Fewer comments means that the ones you write are
more likely to be read.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e129" id="d0e129"></a>e) In
General</h4>
</div>
<p>I wonder how many other cases you can come up with. Send them to
me and I will collate them for publication. However, in general,
given choice, have a consistent policy.</p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e134" id="d0e134"></a>3) Choose Names
in Context</h3>
</div>
<p>Identifiers are often difficult to choose. To my mind it is
important to avoid duplication of information. For example, in the
context of a <tt class="classname">Date</tt> class, is it necessary
to call a member function <tt class="methodname">getmonth</tt> or
<tt class="methodname">printdate</tt> rather than <tt class=
"methodname">month</tt> or <tt class="methodname">print</tt>? The
scope in which an identifier is declared is important, if you do
not use that information when choosing a name then you will be
providing over-long names that will make your code harder to
follow.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e154" id="d0e154"></a>4) Understand
Lexical Conventions</h3>
</div>
<p>Using only uppercase letters in an identifier is sometimes
called 'shouting.' Just like actual shouting it adds nothing to the
process of understanding (indeed shouting often makes it harder to
understand) but it is supposed to stand out as a warning. We shout
to demand attention, we write in all uppercase to demand attention.
There is no need to do this just because something is a constant
(enumeration value or const qualified value). However there is
every reason to do so when we want to warn the reader that what
they see may not be what they get. In this context it makes perfect
sense to use all uppercase (or more accurately 'no lowercase')
identifiers for the pre-processor exactly because they will be
substituted by something else before the tokeniser sees your
code.</p>
<p>Remember that some idioms are just an unspoken agreement to do
things the same way; the advantage is purely that and nothing more.
In other cases idioms serve a deeper purpose, one that is intended
to keep us out of trouble. One of the things that profoundly annoy
me about so many books and courses for novices is that the
authors/presenters do not understand this. Most idioms are not just
issues of personal taste; they keep you from trouble and make your
code more accessible to those reading it.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e161" id="d0e161"></a>Mainly
Semantic</h2>
</div>
<p>Now let me explore some of those things that have a deeper
impact on your code. There are two major tools available that every
competent programmer should be familiar with; delegation and
proxying. One of the major advantages of C++ is that it supports
both these things very well.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e166" id="d0e166"></a>1) Forwarding
Functions</h3>
</div>
<p>I remain profoundly puzzled as to why these are not better known
and more widely used. I hope that by the time you have finished
reading this you will be asking that C++ completes its support by
allowing a constructor to forward to another constructor for the
same type.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e171" id="d0e171"></a>a) Delegation v
Default Arguments</h4>
</div>
<p>There are two things about default arguments that make them
unattractive. The first is that you can only default from the right
hand end of the parameter list (but be careful because declarations
including defaults can be combined, I will say no more about this
because I think that doing any such thing is nauseating). Surely a
method that allows you to provide a default for any combination of
arguments would be preferable? The second issue is that
declarations of the same function in different translation units
can have different default arguments. For example the following is
perfectly legal:</p>
<pre class="programlisting">
File1.cpp
void foo (int val = 0) { cout &lt;&lt; val; }
File2.cpp
void foo (int val = 1);
</pre>
<p>To see just how bad this might be consider:</p>
<pre class="programlisting">
File3.h
extern inline void bar() { foo(); }
</pre>
<p>Now include that header file after the declaration of <tt class=
"function">foo</tt> in each of File1.cpp and File2.cpp. You now
have a breach of the one definition rule. Yes, I realise that this
code is simplistic but my purpose is to provide a minimalist
example of the potential for error. Oh, and the reason for that
extern qualification is to make it clear that <tt class=
"function">bar()</tt> has external linkage as opposed to the older
convention that inline functions had internal linkage.</p>
<p>Now let me return to the theme of eliminating default arguments
from your code. Every time you use a default argument you could use
delegation via a forwarding function instead. So I can replace:</p>
<pre class="programlisting">
void foo (int val = 0) { cout &lt;&lt; val; }
</pre>
<p>with</p>
<pre class="programlisting">
void foo (int val ) { cout &lt;&lt; val; }
inline void foo() { return foo(0); }
</pre>
<p>Indeed the syntax of the language was actually modified to allow
such functions to work even when the return type is void. That
change was mainly to support forwarding functions in the case of a
template, where the return type might be a template type parameter,
but it works in the general case.</p>
<p>Note that this method of replacing defaults is more powerful
than what it replaces. We can use a forwarding function with the
same name to provide a 'default value for any combination of
parameters as long as the resulting list of parameter types is
unique. For example:</p>
<pre class="programlisting">
double foo2(int val, double d, std::string message);
double foo2 () 
  {return foo2(0, 0.0, &quot;trivial&quot;); }
double foo2 (int val)
  {return foo2(val, 0.0, &quot;int given&quot;); }
double foo2 (double d)
  {return foo2(0, d, &quot;double given&quot;); }
double foo2 (std::string message)
  {return foo2(0, 0.0, message); }
double foo2 (int val, double d)
  {return foo2(val, d, &quot;no message&quot;); }
double foo2 (int val, std::string mess)
  {return foo2(val, 0.0, mess); }
double foo2(double d, std::string mess)
  {return foo2(0, d, message); }
</pre>
<p>Even without use of the inline keyword most modern compilers
will inline such simple forwarding functions as a standard
optimisation.</p>
<p>Are there any other advantages? Well yes, if the need arises you
can take the address of any or all of the forwarding functions, of
course when you do so the compiler will have to provide an
instantiation and forgo the luxury of just using it inline (though
that does not prevent it from doing so when it can).</p>
<p>Another advantage is when we want to compute a 'default'
parameter from arguments that have been provided. The calculation
can be done in the body of the forwarding function, thus avoiding
any risk that we will enter the realms of undefined behaviour
because the arguments for a function call can be evaluated in any
order. For example:</p>
<pre class="programlisting">
double foo3(int val, int val2 = val*2);
</pre>
<p>might seem reasonable until you realise that there is no
requirement for arguments to be evaluated in left to right
sequence, though it is hard to see how a compiler would mess that
one up. However we do not even need to consider the problem if we
use a forwarding function because we can fully determine the order
of evaluation:</p>
<pre class="programlisting">
double foo3(int, int);
double foo3(int val)
  { return foo3(val, val*2); }
</pre>
<p>The crux of this is that forwarding functions can do everything
that default arguments can achieve and more. So why use a lesser
technique when a more general one is hardly more difficult - yes,
you do have to do a little more typing.</p>
<p>There is an exception to this and that is default arguments for
constructors; there is no way of forwarding from one constructor to
another. I find that less than convenient (there really is no
reason for constructors to be a special case. Therefore I am
gathering opinions on a proposal for an extension to C++ to provide
syntax for forwarding from one constructor to another. In simple
terms I am proposing that where there is a sole entry in the
constructor-initialiser list for a type that is itself a
constructor for that same type, then the construction is delegated
to that constructor.</p>
<p>Example: (NOT VALID currently)</p>
<pre class="programlisting">
class mytype {
  int val;
  long int anval;
  double dval;
public:
  mytype(int, long, double);
  mytype():mytype(0, 1L, 0.0) { /* the body of this ctor is run immediately on return from the delegated ctor */ }
  // etc.
};
</pre>
<p>This is only one of a number of extensions that I would like to
propose for the next C++ standard. If you are interested, I would
also like to see consideration of const constructors and a method
for inheriting both the implementation and the interface of a base
class without allowing the implicit conversion from derived to
base.</p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e226" id="d0e226"></a>2) Issues of
const correctness</h3>
</div>
<p>There are a number of places where we have to give careful
consideration to the impact of <tt class="literal">const</tt>
qualification on our code. There are several idioms that help with
this; once you know them and apply them automatically you will find
that your clients have fewer surprises.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e234" id="d0e234"></a>a) Overloading
to retain correct const qualification</h4>
</div>
<p>A functions that takes an input parameter, does something with
it that does not mutate it and then returns it are particularly
vulnerable to adding unwanted const qualification. There are
several such functions in the Standard C Library (which you
remember is also part of the Standard C++ Library), but rather than
pick on one let me give you a general function of that form.</p>
<p>Consider a function that takes a null terminated array of char
as input, and determines where the next word begins. It returns a
pointer to that position. So its declaration might be:</p>
<pre class="programlisting">
char * nextword( char * );
</pre>
<p>The problem with this is that you cannot use it on an array of
<span class="type">const char</span>. So your next shot is:</p>
<pre class="programlisting">
char * nextword( char const * );
</pre>
<p>Unfortunately that does not work, because the returned pointer
is pointing into the array that was passed as <tt class=
"literal">const</tt> qualified. Now you must try:</p>
<pre class="programlisting">
char const * nextword( char const * );
</pre>
<p>That works fine until the day dawns when you want to modify the
returned sub-array. For example:</p>
<pre class="programlisting">
void capitalise(char * data){
  while (*data) {
    data[0] = toupper(data[0]);
    data = nextword(data);  // ERROR
  }
}
</pre>
<p>You see the problem? <tt class="function">nextword()</tt> has
added a <tt class="literal">const</tt> qualifier and so its return
value cannot be held in a plain <span class="type">char*</span>
variable. In this particular case we can safely use a <tt class=
"literal">const_cast</tt> to solve the problem (well we could apart
from that dratted deprecated conversion from string literal to
<span class="type">char*</span>, but that is another problem that I
will deal with in a moment):</p>
<pre class="programlisting">
void capitalise(char * data){
  while (*data) {
    data[0] = toupper(data[0]);
    data = const_cast&lt;char *&gt;nextword(data);  // OK
  }
}
</pre>
<p>But we really do not want to force this kind of code on our
clients when we can do it for free for them. A simple forwarding
function solves this problem at compile time with no runtime
overhead. We just add the following function:</p>
<pre class="programlisting">
inline char * nextword( char * arr){
  return const_cast&lt;char *&gt; nextword(static_cast&lt;char const *&gt; arr);
}
</pre>
<p>The <tt class="literal">static_cast</tt> forces the selection of
the <tt class="literal">const</tt> version of <tt class=
"function">nextword()</tt>, the <tt class="literal">const_cast</tt>
strips off the <tt class="literal">const</tt> qualification, and
can do so safely because that qualification was just an artefact of
calling <tt class="function">nextword()</tt>. There is no runtime
overhead because the compiler needs to do nothing, our code just
prevents the accidental acquisition of a <tt class=
"literal">const</tt> qualification.</p>
<p>While you do not need to write this kind of code often, you
should be familiar with how to do it when necessary.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e310" id="d0e310"></a>b) Handling
string literals</h4>
</div>
<p>For many years C++ suffered from the problem that string
literals were syntactically arrays of <span class=
"type">char</span>, but semantically arrays of <span class=
"type">const char</span>. There was a great deal of code that
included lines such as:</p>
<pre class="programlisting">
char * mess = &quot;string literal&quot;;
</pre>
<p>Very late in the day, a paper written by Kevlin Henney finally
changed the type of a string literal to array of <span class=
"type">const char</span>. However it was necessary to minimise
damage to existing code. For that reason the C++ Standard provides
a special conversion from string literal to <span class=
"type">char*</span>. It is only available when it is necessary to
convert an actual string literal to a <span class=
"type">char*</span>. For example:</p>
<pre class="programlisting">
char * mess = &quot;string literal&quot;;  // OK
char const * mess1 = &quot;another string literal&quot;;
char * mess = mess1; // ERROR, mess1 is not a string literal
</pre>
<p>Now there is nothing we can do to prevent:</p>
<pre class="programlisting">
capitalise(mess);
</pre>
<p>because mess is of type <span class="type">char*</span>.</p>
<pre class="programlisting">
capitalise(mess1);
</pre>
<p>will fail because capitalise requires a plain <span class=
"type">char*</span>. Unfortunately:</p>
<pre class="programlisting">
capitalise(&quot;this is a problem&quot;)
</pre>
<p>compiles even though the result is undefined behaviour. There is
a simple fix to this problem, just declare an appropriate overload
of capitalise:</p>
<pre class="programlisting">
void capitalise(char const *);
</pre>
<p>Be careful that you do not define it. Now string literals will
try to use this overload and the linker will generate an error. The
failure is later than ideal, but earlier than a segment fault at
runtime.</p>
<p>Whenever you write a function that takes a parameter of type
<span class="type">char*</span>, consider overloading it for
parameters of type <span class="type">char const *</span>, but do
not define those overloads.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e368" id="d0e368"></a>c) Overloading
const and non-const member functions</h4>
</div>
<p>There are two problems here. The first one is that the compiler
selects on the basis of the qualification of the object using the
function. This often causes surprises but I am going to leave the
exploration of this till another time.</p>
<p>The second problem is when you write something such as:</p>
<pre class="programlisting">
class problem {
public:
  void foo(int);
  void foo(char) const;
// rest of class
};
int main(){
  problem p;
  p.foo('a');
  return 0;
}
</pre>
<p>Now, I know such code is silly, but the point I want to make is
that it also will not compile (with a conforming compiler). Many
people are surprised by this because they feel that clearly
<tt class="methodname">void foo(char) const</tt> should be selected
in preference to <tt class="methodname">void foo(int)</tt>. They
are wrong. The language rules require that the selected function
from an overload set must be at least as good a match on each
parameter, and better on at least one. The problem is that, as a
member function, foo has two parameters in each case. Even though
the conversion from plain to <tt class="literal">const</tt> is
about as trivial as you can get, it is still not a pure identity
(though one part of the C++ Standard actually describes it as an
identity conversion). Now, if you look back at that code you will
see that <tt class="methodname">void foo(int)</tt> is a better
match for the implicit parameter while <tt class="methodname">void
foo(char) const</tt> is a better match on the explicit parameter. A
conforming compiler has no choice but to declare 'ambiguity'.</p>
<p>If you overload member functions with different explicit
parameters, you will almost certainly need to provide
non-<tt class="literal">const</tt> versions of any that are
<tt class="literal">const</tt> member functions. The non-<tt class=
"literal">const</tt> version can usually delegate to the <tt class=
"literal">const</tt> version.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e408" id="d0e408"></a>d) The subscript
operator</h4>
</div>
<p>The subscript operator is a very special case. The problem is
that its use will usually expose a detail of the implementation.
The <tt class="literal">const</tt> version:</p>
<pre class="programlisting">
sometype const &amp; operator[](keytype) const;
</pre>
<p>is not a great problem. You should always remember that the
reference might be invalidated by some subsequent call of another
member function, but this is a general rule. The only way that I
know to protect against that kind of abuse is to return by value,
the language does not provide support for restricting behaviour of
reference types (if you know different, please write an article on
the subject). On the other hand we can do something to handle
potential problems generated by the non-<tt class=
"literal">const</tt> version. We want to prevent the information
leaking out into the program as a whole. Basically there are two
cases to deal with. The first is just that if the object is
non-<tt class="literal">const</tt> it will use the non-<tt class=
"literal">const</tt> <tt class="methodname">operator[]</tt>. That
is fine if we want to use it as an rvalue (i.e. just as a pure
value) because if that is all we wanted we could delegate to the
<tt class="literal">const</tt> version. However, users will also
want to use the return as an lvalue, in other words they will want
to assign to it. Somehow we need to capture and control assignment
to a subscripted object. I need to support both:</p>
<pre class="programlisting">
sometype s;
s = container[n];
</pre>
<p>and</p>
<pre class="programlisting">
container[n] = s;
</pre>
<p>It is the second that causes the problem. Fortunately there is a
perfectly good idiom to solve this problem in a way that provides
just enough access for the assignment. The following is the merest
sketch:</p>
<pre class="programlisting">
class container {
public:
  class ref {
  public:
    ref(sometype *);
    void operator= (sometype const &amp;);
    operator sometype const &amp; ();
  private:
    sometype * data_ptr;
  };
  ref &amp; operator[](keytype); 
... // other details
};
</pre>
<p>Now when you use the subscript operator on a non-<tt class=
"literal">const</tt> instance of <tt class=
"classname">container</tt> you will get a writable reference to a
<span class="type">container::ref</span> back. This gives us the
chance to grab and manage the <tt class=
"methodname">operator=()</tt> and make it do the right thing.
Anyone who tries to hang on to that by having some variable of type
<span class="type">container::ref</span> (or a pointer or reference
to same) will find that there is very little they can do with it.
Well that is too restrictive, because that would get in the way of
using the subscript operator as an rvalue. This is the reason for
that conversion operator in <span class=
"type">container::ref</span>. Note that that conversion operator
has another interesting feature in that it blocks any further
implicit conversions with user defined conversion operators for
sometype, as well as any use of converting constructors that take a
sometype argument.</p>
<p>Would it be useful to have the <tt class=
"methodname">operator[]()const</tt> return a <span class=
"type">container::ref &amp; const</span>? I am not sure and I have
run out of time.</p>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e473" id=
"d0e473"></a>Conclusion</h2>
</div>
<p>The purpose of this article is primarily to start the ball
rolling. There are many idioms, both techniques and useful customs
that expert C++ programmers use and assume are obvious. We need to
record these for the benefit of the multitudes of good and aspiring
programmers who have not come across them. Delve away into how you
write code and ask yourself just how obvious your idioms are. Now
write them up, in the first instance to share them with others, but
secondly to expose them to the critical eye of others. The
important thing is not just that I can teach you something but that
you can teach me. Until I tell you what I know or believe, you can
neither learn from me nor correct my mistakes.</p>
<p>If you find yourself doing something because you trust my
authority, you are definitely wrong. That last sentence applies
whoever you are and whoever I am. Under pressure of time, trust me,
but when you have more time, challenge my thinking - you owe it to
both of us.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
