    <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++ Lookup Mysteries</title>
        <link>https://members.accu.org/index.php/journals/242</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>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #63 - Oct 2004 + Programming Topics</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/journals/">All</a>

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c149/">63</a>
                    (6)
<br />

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

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

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

                                            <a href="https://members.accu.org/index.php/journals/c149-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c149+65/">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++ Lookup Mysteries</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 01 October 2004 16:25:38 +01:00 or Fri, 01 October 2004 16:25:38 +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 day, my friend Tommy asked me why his C++ code failed. He
wanted to print out a number of objects (of his own class) to a
stream. It worked well with a plain for-loop and an output operator
(<tt class="methodname">&lt;&lt;</tt>), so he knew that his output
operator for the class worked as intended. But when he used
<tt class="classname">std::copy()</tt> and <tt class=
"classname">std::ostream_iterator</tt> it failed. He wanted to &quot;go
STL&quot; because everyone, myself included, was telling him how great
the STL is.</p>
<p>It took us a while to figure out what was wrong and it brought
us down the dark sides of the inner workings of C++. It was an
interesting experience and one that I would like to share.</p>
<p>This article investigates function lookup in C++ and also
contains a suggestion of what to do when you want to use several
different output formats and still use output operators and
STL.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e35" id="d0e35"></a>The Code</h2>
</div>
<p>Tommy used a class developed for a toolbox. This toolbox was
declared inside a namespace, following project guidelines to avoid
name collisions. Namespaces were considered good and were used a
lot throughout the project.</p>
<p>Tommy followed the guidelines and put the toolbox client code in
a different namespace. In here he had a need to print out objects
of this new class stored in a container. He wrote a function that
iterates over the container and an output operator for this
purpose. His code was something like this:</p>
<pre class="programlisting">
namespace Client {
  std::ostream &amp; operator&lt;&lt;(std::ostream &amp;os, 
                   Tools::Spanner const &amp; s) {
    os &lt;&lt; &quot;Spanner{ID=&quot; &lt;&lt; s.getID() 
       &lt;&lt; &quot;, gapSize=&quot; &lt;&lt; s.getGapSize() 
       &lt;&lt; &quot;}&quot;;
    return os;
  }

  void printSpanners(std::ostream &amp; os, 
                  Tools::Toolbox const &amp; tb) {
    for(Tools::SpannerCollection
             ::const_iterator sit
                   = tb.getSpanners().begin();
        sit != tb.getSpanners().end();
        ++sit) {
      os &lt;&lt; *sit &lt;&lt; &quot;\n&quot;;
    }
  }
}
</pre>
<p>This code worked nicely. He then introduced some STL-isms and
rewrote the printing function to use <tt class=
"classname">std::copy()</tt> and <tt class=
"classname">std::ostream_iterator</tt>. These functions are often
together in C++ books to show the power and flexibility of the STL.
An <tt class="classname">std::ostream_iterator</tt> is an output
iterator and is used with algorithms in the same way as any other
output iterator. When an object is assigned to a dereferenced
<tt class="classname">std::ostream_iterator</tt>, this object is
written to the output stream that the <tt class=
"classname">std::ostream_iterator</tt> was constructed with, using
an output operator defined for that object. The <tt class=
"classname">std::ostream_iterator</tt> is specialised with a type
of the objects it shall print out. The constructor of <tt class=
"classname">std::ostream_iterator</tt> can also take an optional
second parameter that will be used as separator string between the
printed objects. Every time an object is assigned through an
<tt class="classname">std::ostream_iterator</tt>, that object is
printed to the <tt class="classname">std::ostream</tt> object using
the output operator.</p>
<p>The rewritten output operator code looked something like
this:</p>
<pre class="programlisting">
namespace A {
  void f(int);
  void g(int);
  
  namespace B {
    void f(double);      // hides A::f(int)
    void g(const char*); // hides A::g(int)
    void caller() {
      f(1); // calls A::B::f(double)
      g(1); // error: cannot convert '1' 
            // to a 'const char*'
    }
  }
}
</pre>
<p>In this example we see that <tt class=
"methodname">A::B::f(double)</tt> hides <tt class=
"methodname">A::f(int)</tt> and is thus the only function
considered in the first call. The <tt class="type">int</tt>
argument can be converted to <tt class="type">double</tt> so this
call is legal.</p>
<p>In the same way, <tt class="methodname">A::B::g(const
char*)</tt> hides <tt class="methodname">A::g(int)</tt>. But the
<tt class="type">int</tt> argument in the second call cannot be
converted to a pointer and the call is illegal.</p>
<p>Note that <tt class="methodname">A::g(int)</tt> is not
considered at all, even though <tt class="methodname">A::B::g(const
char*)</tt> cannot be used in the call.</p>
<p>After searching the current and enclosing namespaces, any
functions with the same name are searched in namespaces associated
with the types of the arguments to the function. This second part
is called argument-dependent-lookup (a.k.a. ADL or Koenig-lookup).
Consider:</p>
<pre class="programlisting">
class X {};
void f(const X &amp;);

namespace A {
  class Y : public X {};
  void f(const Y &amp;);
}

void caller() {
  A::Y y;
  f(y);  // calling A::f(const Y &amp;);
}
</pre>
<p>Both functions <tt class="function">f(const X &amp;)</tt> and
<tt class="function">A::f(const Y &amp;)</tt> are found by the
lookup rules and considered for overload resolution. <tt class=
"function">f(const X &amp;)</tt> is found by looking at the nearest
namespace and <tt class="function">A::f(const Y &amp;)</tt> is
found using argument-dependent-lookup.</p>
<p>The argument <i class="parameter"><tt>y</tt></i> has a type
defined in namespace <tt class="literal">A</tt> where the function
<tt class="function">A::f(const Y &amp;)</tt> is found. The
overload resolution rule looks at both functions and chooses
<tt class="function">A::f(const Y &amp;)</tt> as a better
match.</p>
<p>So, in the function <tt class="function">printSpanners()</tt>,
using the for loop, we find the output operator in the same
namespace (<tt class="literal">Client</tt>). If the output operator
was declared in the global namespace instead, we would find it
there, unless there were other output operators in the namespace
<tt class="literal">Client</tt>. The namespace <tt class=
"literal">Tools</tt> would also be looked at as the argument type
<tt class="classname">Spanner</tt> is declared there, but there are
no output operators there.</p>
<p>The problem for Tommy is that when <tt class=
"classname">std::copy()</tt> is used, the first stage of the search
starts in the namespace <tt class="literal">std</tt>, and not in
namespace <tt class="literal">Client</tt>. This is because the call
to the output operator is from within the function body of
<tt class="classname">std::copy()</tt>. Namespace <tt class=
"literal">std</tt> has a number of output operators as defined in
the C++ standard in order to facilitate formatted output of any
built-in type and some types defined in the C++ library. It doesn't
matter that none of these overloaded output operators can be used
with <tt class="classname">Spanner</tt>. The lookup rule says that
we find the function in the nearest enclosing namespace and stop.
The output operator defined in the namespace <tt class=
"literal">Client</tt> is not considered at all as this namespace is
not an enclosing namespace of namespace <tt class=
"literal">std</tt>. The compiler won't even find the output
operator if it was defined in the global namespace as it had
already found some output operators in namespace <tt class=
"literal">std</tt>, its nearest namespace.</p>
<p>Had Tommy declared the output operator in the same namespace as
the class (namespace <tt class="literal">Tools</tt>), he would have
avoided this problem as the second rule (ADL) would have found it.
It can be seen as part of the interface of the class and should be
declared close to the class itself, preferably in the same header
file. This is fine if you have control over the header file. It
does not work if the header is part of a third party library. As a
workaround it is possible to put the declaration in any header file
by re-opening the namespace like this:</p>
<pre class="programlisting">
namespace Tools {
  std::ostream &amp; operator&lt;&lt;(std::ostream &amp; os, 
                          Spanner const &amp; s) {
    ...
  }
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e195" id="d0e195"></a>The Real
Problem</h2>
</div>
<p>So what was Tommy trying to do? Why was the output operator
declared in the <tt class="literal">Client</tt> namespace and not
in the <tt class="literal">Tools</tt> namespace where it belongs?
Tommy said that he could have added the output operator in the
<tt class="literal">Tools</tt> namespace, but he wanted different
output formats for different client applications. He couldn't place
the output operators beside the <tt class="classname">Spanner</tt>
class definition as you can only have one of them in the same
namespace. There is no way to overload two output operators with
another parameter. For his project it was easy to use namespaces to
separate the output operators as no client in the same namespace
would use more than one format.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e212" id="d0e212"></a>A Solution to
the Real Problem</h2>
</div>
<p>So how can we make a design where we can have different output
formats? How can we use these formats using output operators? And
how can we make a design that will work when we use <tt class=
"classname">std::copy()</tt> and <tt class=
"classname">std::ostream_iterator</tt>?</p>
<p>To start this off, we want some way to select different formats
when a <tt class="classname">Spanner</tt> object is printed to a
stream. Possibly you could derive from <tt class=
"classname">Spanner</tt> and then overload the output operator on
these derived classes. Not a very nice design and it won't work as
you cannot downcast a <tt class="classname">Spanner</tt> object to
the derived class.</p>
<p>A simpler approach is to use different named functions that do
the formatting. We want a simple syntax such as:</p>
<pre class="programlisting">
std::cout &lt;&lt; spanner.printNameAndGap()
          &lt;&lt; std::endl;
</pre>
<p>This can be implemented by letting the member function
<tt class="function">printNameAndGap()</tt> return a string in the
format we want. Nice and simple. Except that it is not always
possible to add things to the class we are using, for example third
party libraries. Here, the formatting belongs to the user, not to
the class itself. The class designer does not know what format all
clients can possibly want to use. This approach is also
inefficient, as a temporary string has to be created.</p>
<p>Instead we want to use a non-member function and we want writes
made directly to the output stream. This function can return an
object of a class that can be used with an overloaded output
operator. To make it easy, we use the constructor of this
formatting class instead of a separate function.</p>
<pre class="programlisting">
class PrintSpannerNameAndGap {
public:
  PrintSpannerNameAndGap(Spanner const &amp; s) 
      : m_s(s) {}
  void print(std::ostream &amp; os) const {
    os &lt;&lt; &quot;Spanner{ID=&quot; &lt;&lt; s.getID() 
       &lt;&lt; &quot;, gapSize=&quot;
       &lt;&lt; s.getGapSize() 
       &lt;&lt; &quot;}&quot;;
    return os;
  }
private:
  Spanner const &amp; m_s;
};

std::ostream &amp; operator&lt;&lt;(std::ostream &amp; os,
                 PrintSpannerNameAndGap
                           const &amp; spanner) {
  spanner.print(os);
  return os;
}
</pre>
<p>We can now use this class like this:</p>
<pre class="programlisting">
std::cout &lt;&lt; PrintSpannerNameAndGap(spanner)
          &lt;&lt; std::endl;
</pre>
<p>This does not look too bad. Just watch out for that member
reference to the original object. The <tt class=
"classname">PrintSpannerNameAndGap</tt> object must not exist
longer than the referenced <tt class="classname">Spanner</tt>
object. This is not a problem when it is used as shown above as it
only exists as a temporary object and disappears at the end of the
statement.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e259" id="d0e259"></a>Using
<tt class="classname">std::copy()</tt> and <tt class=
"classname">std::ostream_iterator</tt></h2>
</div>
<p><tt class="classname">std::copy()</tt> is nice but it is not
possible to insert a formatting object in the way shown above. We
have to look at other ways to indicate that we want different
output.</p>
<p>If we look at the line using <tt class=
"classname">std::copy()</tt> and <tt class=
"classname">std::ostream_iterator</tt> there aren't many
opportunities for modification. We could adapt the source iterators
(the begin/end pair) to return a different object when
dereferenced, and define an output operator for each different
object type. The mechanism for choosing the correct overloaded
output operator would be similar to the approach above.</p>
<p>But there is no need to create the iterator adaptor. We only
have to specify to the <tt class=
"classname">std::ostream_iterator</tt> that it shall work with
<tt class="classname">PrintSpannerNameAndGap</tt> objects. This
makes the code much simpler:</p>
<pre class="programlisting">
std::copy(tb.getSpanners().begin(), 
          tb.getSpanners().end(), 
          std::ostream_iterator&lt;
                 PrintSpannerNameAndGap&gt;(
                                os, &quot;\n&quot;));
</pre>
<p><tt class="classname">PrintSpannerNameAndGap</tt> is the same
class as above. As the <tt class=
"classname">std::ostream_iterator</tt> requires a <tt class=
"classname">PrintSpannerNameAndGap</tt>, then the <tt class=
"classname">Spanner</tt> objects returned by the source iterators
are implicitly converted to <tt class=
"classname">PrintSpannerNameAndGap</tt> objects. This works because
we did not make the constructor explicit. The <tt class=
"classname">PrintSpannerNameAndGap</tt> object is a temporary
object and is deleted after the assignment statement in <tt class=
"classname">std::copy()</tt> has completed. The <tt class=
"classname">PrintSpannerNameAndGap</tt> object holds a reference to
the <tt class="classname">Spanner</tt> object coming from the
iterators to avoid unnecessary copying. This reference is OK as the
<tt class="classname">PrintSpannerNameAndGap</tt> object has
shorter lifetime than the <tt class="classname">Spanner</tt>
object.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e323" id="d0e323"></a>Possible
Improvements</h2>
</div>
<p>We could use templates to reduce the amount of boilerplate code.
But introducing templates does not reduce enough code to motivate
the extra complexity.</p>
<p>Another approach would be to let the formatting class <tt class=
"classname">PrintSpannerNameAndGap</tt> inherit from a base class
that is used by all classes supporting different output formats.
This base class would keep the reference to <tt class=
"classname">Spanner</tt> and declare the function <tt class=
"methodname">print()</tt> pure virtual. A single output operator
definition for this base class replaces all specific output
operators. This only pays off when there are many different output
formats for the same object type.</p>
<p>A specific functor object can be used with the C++ library
algorithm <tt class="classname">std::for_each()</tt> to print out
each element. Initialise the functor with the output stream and
define an <tt class="function">operator()(Spanner const &amp;)</tt>
that prints each object to the output stream in the required
format.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e347" id=
"d0e347"></a>Conclusion</h2>
</div>
<p>It is not always easy to understand what happens under the hood
in C++. But there are solutions to every problem even if good
understanding of C++ may be required. Don't be afraid of asking
friends or other ACCU members for advice.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e352" id=
"d0e352"></a>Acknowledgements</h2>
</div>
<p>Thanks to Tommy Persson who had the problem originally and spent
time describing the problem to me, to Richard Corden for clarifying
the C++ standard and to Thaddaeus Frogley for reviewing.</p>
<i><span class="remark">[The name lookup rules in C++ are not only
confusing for the non-expert, they present serious problems to the
expert. One such expert (Dave Abrahams) has presented these
problems, and proposed a solution, for consideration by the
standards committee: <a href=
"http://www.boost-consulting.com/writing/n1691.html" target=
"_top">http://www.boost-consulting.com/writing/n1691.html</a> -
Alan (ed)]</span></i></p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
