Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You need to move your implementation of <code>operator&lt;&lt;</code> into the same namespace as your class. It's looking for:</p> <pre><code>ostream&amp; operator&lt;&lt; (ostream&amp; os, const skg::Triplet&lt;T&gt;&amp; p_t) </code></pre> <p>But won't find it because of a short-coming in argument-dependent look-up (ADL). ADL means that when you call a free function, it'll look for that function in the namespaces of it's arguments. This is the same reason we can do:</p> <pre><code>std::cout &lt;&lt; "Hello" &lt;&lt; std::endl; </code></pre> <p>Even though <code>operator&lt;&lt;(std::ostream&amp;, const char*)</code> is in the <code>std</code> namespace. For your call, those namespaces are <code>std</code> and <code>skg</code>.</p> <p>It's going to look in both, not find one in <code>skg</code> (since yours is in the global scope), then look in <code>std</code>. It will see possibilities (all the normal <code>operator&lt;&lt;</code>'s), but none of those match. <em>Because the code running (the code in <code>ostream_iterator</code>) is in the namespace <code>std</code>, access to the global namespace is completely gone.</em></p> <p>By placing your operator in the same namespace, ADL works. This is discussed in an article by Herb Sutter: <em><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1792.pdf" rel="noreferrer">"A Modest Proposal: Fixing ADL."</a></em>. (PDF). In fact, here's a snippet from the article (demonstrating a shortcoming):</p> <pre><code>// Example 2.4 // // In some library header: // namespace N { class C {}; } int operator+( int i, N::C ) { return i+1; } // A mainline to exercise it: // #include &lt;numeric&gt; int main() { N::C a[10]; std::accumulate( a, a+10, 0 ); // legal? not specified by the standard } </code></pre> <p>Same situation you have.</p> <p>The book <em>"C++ Coding Standards"</em> by Sutter and &amp; Alexandrescu has a useful guideline:</p> <blockquote> <ol start="57"> <li>Keep a type and its nonmember function interface in the same namespace.</li> </ol> </blockquote> <p>Follow it and you and ADL will be happy. I recommend this book, and even if you can't get one at least read the PDF I linked above; it contains the relevant information you should need.</p> <hr> <p>Note that after you move the operator, you'll need your friend directive (so you can access private variables):</p> <pre><code>template &lt;typename U&gt; friend ostream&amp; operator&lt;&lt; (ostream&amp; os, const Triplet&lt;U&gt;&amp; p_t); </code></pre> <p>And ta-da! Fixed.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload