Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The simple answer is yes, you can do <code>file &gt;&gt; myWord;</code>, as long as you've defined the <code>&gt;&gt;</code> operator for your class:</p> <pre><code>std::ostream&amp; operator&gt;&gt;( std::ostream&amp; source, Word&amp; word ) { // ... return source; } </code></pre> <p>Several considerations:</p> <ul> <li><p>This operator cannot be a member; it must be a free function. (If it were a member, your class would be the left hand argument.) If it needs to access private data, you might have to make it a <code>friend</code>. </p></li> <li><p>Don't forget about error checking, and the conventions of <code>istream</code> for errors. If you encounter input you cannot parse into your class, you need to set <code>std::ios::failbit</code>. (Of course, a lot of the time, you'll be delegating to previously defined <code>&gt;&gt;</code>, and if they fail, <code>std::ios::failbit</code> will already have been set.)</p></li> </ul> <h2>EDIT:</h2> <p>As for what you should do inside the newly overloaded operator, there are several possibilities (which can, with care, be mixed):</p> <ul> <li><p>You can invoke existing <code>&gt;&gt;</code>, for example, for strings or built-in types. This is by far the easiest, but it supposes that your input can easily be parsed uniquely in terms of existing <code>&gt;&gt;</code>, which is rarely the case.</p></li> <li><p>You can also use unformatted input, like <code>istream::get()</code>, this is most often used in parallel with the previous solution, to input things like separators, or other syntactical elements of your format.</p></li> <li><p>Or you can do revert to reading the bytes directly from the <code>streambuf</code>, and parse them. This is appropriate if you have some totally new type, for example. If you go this route, do <em>not</em> forget to set <code>eofbit</code> if you read an end of file, even if you can successfully parse otherwise. If you do this, you'll also have to create a <code>sentry</code> object at the top of your <code>&gt;&gt;</code>, and only proceed if it is good. (It is only in such <code>operator&gt;&gt;</code> that <code>std::ios::good</code> makes sense. You must never try to read a character from the streambuf if <code>std::ios::good()</code> returns false, and you must set <code>std::ios::eofbit</code> anytime you read an EOF (which will cause all future calls to <code>std::ios::good()</code> to return false). This is so essential that I tend to use a small wrapper object for it, and read through it.</p></li> </ul> <p>In all cases, you may have to play around with the formatting information: as a simple example, if you don't want to allow white space within your input, but you are still using <code>&gt;&gt;</code>, you should set <code>nows</code> (and restore it at the end). Thus, most such <code>&gt;&gt;</code> operators will start by saving the formatting status, and restore it at the end. (This is usually done by means of an <code>IOSave</code> class, which you should have in your toolkit anyway.) And again, if something in the input format is incorrect, you should set <code>failbit</code>.</p> <p>As a simple example, consider a <code>&gt;&gt;</code> for a simple <code>Complex</code> class:</p> <pre><code>std::istream&amp; operator&gt;&gt;( std::istream&amp; source, Complex&amp; dest ) { IOSave state( source ); // Skip leading whitespace, depending on formatting options. if ( (source.flags() &amp; std::ios_base::skipws) != 0 ) { source &gt;&gt; std::ws; } source.unsetf( std::ios_base::skipws ); std::streamsize totalWidth = std::max( source.width() - 3, std::streamsize(0) ); ; std::streamsize imagWidth = totalWidth / 2; std::streamsize realWidth = totalWidth - imagWidth; if ( source.get() != '(' ) { source.unget(); source.setstate( std::ios::failbit ); } double real = 0.0; source &gt;&gt; std::setw( realWidth ) &gt;&gt; real; std::numpunct&lt;char&gt; const&amp; np = std::use_facet&lt;std::numpunct&lt;char&gt;&gt;( source.getloc() ); if ( std::get() != (np.decimal_point() != ',' ? ',' : ';') ) { source.unget(); source.setstate( std::ios::failbit ); } double imag = 0.0; source &gt;&gt; std::setw( imagWidth ) &gt;&gt; imag; if ( std::peek() != ')' ) { source.unget(); source.setstate( std::ios::failbit ); } if ( source ) { dest = Complex( real, imag ); } return source; } </code></pre> <p>This is an extremely simplistic example. A real <code>Complex</code> class would, for example, also accept input in the form a+ib. But it should give you an idea of the sort of things you have to consider when writing such an operator.</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. 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.
 

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