Custom stream-like classes Consider the following code:

#include &lt;iostream&gt;
#include &lt;vector&gt;
using namespace std;

struct test {
    int j;
    test&amp; operator&gt;&gt;(int &amp; i) { i = ++j%26; return *this; }
    operator bool() { return j%26; }
};

int main () {
    test t;
    int i;
    while (t &gt;&gt; i) {
        cout &lt;&lt; i &lt;&lt; endl;
    }
}


I have implemented a simple class that can be used in a similar fashion as for example std::cin. I implemented it this way, because I wanted to have an object that hides some IO-operations from me and provide a nice interface to yield the data items each one-at-a-time.

Although it does want I want, I know there is at least one issue with the implementation:


ignorance w.r.t. the safe bool idiom


Are there probably any more?
For simple 10 lines 10 programs you can get away with this:

using namespace std;


Anything bigger and it starts to be a pest more than a help. Thus it best not to get into the habit of using it. Anyway it is simpler even in this case just to prefex cout with std:: (that is why standard is named std to make it short and easy to use).

You don't initialize the value of j in your class.

int j;


Thus any usage is undefined behavior.

You have two options:


Add a constructor that initaizes j
Always force zero-initialization of your class.


In anything but this trivial program I would go with (1) and add a constructor. But just to show zero initialization the alternative is:

 Test  t = Test();  //  The () brackets at the end of Test() force zero initialization;


Note: The equivalent for new is

 Test* t = new Test();  // force zero-initialization (when no constructor)
 Test* t = new Test;    // Use default-initialization (un-initialized)


Note 2: Normally you would think you could do this:

 Test  t(); // Unfortunately this is a forward declaration of a function.


Note 3: But you can get around the problems of (2) by using extra braces.
        As pointed out last time I tried to answer a question like this.

 Test  t(()); // Unfortunately this confuses people and maintainers have been
              // known to try and take out the extra braces. With mixed results.
              // This is why I still prefer method 1

 Test t = Test(); // This may look like there is an extra copy.
                  // But every compiler implements the optimization to do construction
                  // in place.
              // Thus I prefer method 1 (ie this method)


Described here: https://stackoverflow.com/questions/5914422/proper-way-to-initialize-c-structs/5914697#5914697

For such a simple class I don't think you need to worry about the safe bool idium. This just protects your class from being used in places where arithmatic would be done:

 Test t;
 int x = 5 + t;  // Here we get conversion to bool
                 // which is then converted to int (0 or 1)
                 // The safe bool idium would protect you from this:


To use it do this:

 operator bool() { return j%26; }

 // Remove the above and replace with

 operator void*() {return j%26 ? &amp;j /* or this the value is not important as long as it is not NULL */ : NULL; }