Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When overloaded as a member function, <code>a &lt;&lt; b</code> is interpreted as <code>a.operator&lt;&lt;(b)</code>, so it only takes one explicit parameter (with <code>this</code> as a hidden parameter).</p> <p>Since this requires that the overload be part of the class used as the left-hand operand, it's not useful with normal <code>ostream</code>s and such. It would require that your overload be part of the <code>ostream</code> class, not part of your class. Since you're not allowed to modify <code>ostream</code>, you can't do that. That leaves only the global overload as an alternative.</p> <p>There is, however, a fairly widely-used pattern where you overload the operator globally, but have that call a member function:</p> <pre><code>class whatever { // make this public, or the global overload a friend. std::ostream &amp;write(std::ostream &amp;dest) const { // write self to dest } }; std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, whatever const &amp;w) { return w.write(os); } </code></pre> <p>This is particularly useful when/if you want polymorphic behavior. You can't make the overloaded operator polymorphic itself, but you make the member function it calls <code>virtual</code>, so it acts polymorphic anyway.</p> <p>Edit: to (I hope) clarify the situation, you can do this a few different ways. The first and probably most obvious is to just make our <code>write</code> member public, and have the global operator call it. Since it is public, we don't have to do anything special to let the operator use it:</p> <pre><code>class myClass { public: std::ostream &amp;write(std::ostream &amp;os) const { // write stuff to stream return os; } }; std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, myClas const &amp;m) { // since `write` is public, we can call it without any problem. return m.write(os); } </code></pre> <p>A second alternative is to make <code>write</code> private, and declare <code>operator&lt;&lt;</code> a friend to give it access:</p> <pre><code>class myClass { // Note this is private: std::ostream &amp;write(std::ostream &amp;os) const { // write stuff to stream return os; } // since `write` is private, we declare `operator&lt;&lt;` a friend to give it access: friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;, myClass const &amp;); }; std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, myClas const &amp;m) { return m.write(os); } </code></pre> <p>There's a third possibility that's almost like the second:</p> <pre><code>class myClass { // Note this is private: std::ostream &amp;write(std::ostream &amp;os) const { // write stuff to stream return os; } // since `write` is private, we declare `operator&lt;&lt;` a friend to give it access. // We also implement it right here inside the class definition though: friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, myClas const &amp;m) { return m.write(os); } }; </code></pre> <p>This third case uses a rather strange (and little known) rule in C++ called "name injection". The compiler knows that a <code>friend</code> function can't be part of the class, so instead of defining a member function, this "injects" the name of that function into the surrounding scope (the global scope, in this case). Even though <code>operator&lt;&lt;</code> is defined inside the class definition, it's <em>not</em> a member function at all -- it's a global function.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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