My last post triggered a couple of responses and a URL I thought would be good to not get lost in the comments. Check out http://www.artima.com/cppsource/safebool.html.
As I was saying a couple of posts ago, the right tool is usually situational. In my case, things like SafeInt<int>(2) << 3, and int I = SafeInt<unsigned long>(SomeFunc()) not only make sense, but are explicitly supported, and because all of those things are already in place, it’s OK to overload bool. They then go on to talk about operator !, which is also already supported, since you have to be able to get ![some integral type], and you want a SafeInt to behave as closely as possible to the integer type it’s encapsulating.
The safebool trick is pretty neat, but you need to heed the warning about whether the comparison operators do or don’t make sense for your class. They do make sense for a SafeInt (since I want to avoid thinking that -1 == 2^32-1), but probably wouldn’t make sense for another class, though we do want to be able to compare pointers.
What I’m not so sure about is just why the safebool idiom won’t compile in a SafeInt, but given the overall context, I think overloading bool is OK.
Something else I really like about the article is that he also talks about when NOT to use this trick – you’ll run afoul of a lot fewer side effects by creating a isValid() method. Sure, it isn’t cool, or elegant, and it won’t mystify your friends, but there’s a lot to be said for writing code that someone just out of school can understand and use properly.
At any rate, thanks for the comments and the pointer to the interesting article.