結論から先に言いましょう。
C++0x では、 explicit operator bool を定義すれば、自動的に ! 演算子も使えるようになります:
// getchar の戻り値とかで使えそうな何か struct hoge { hoge() : ch_(-1) {} hoge( char ch ) : ch( static_cast<unsigned char>(ch) ) {} explicit operator bool() const { return ch_ != -1; } char operator*() const { return static_cast<unsigned char>(ch); } private: int ch_; }; int main() { hoge x('a'), y; assert( x && *x == 'a' ); assert( !y ); // operator! は用意されてないけど OK }
これは、 ! 演算子の対象が "contextually converted to bool" される*1為で、
"contextually converted to bool" というのは、要するに bool に対する明示的な変換である*2から。
というわけで上記コードの !y
は問題なくコンパイル通ります。
参考: C++0x explicit bool - Faith and Brave - C++で遊ぼう
ちなみに、このことを調べたのは「あれ? std::unique_ptr に operator! ないけど大丈夫なの?」と思ったのがきっかけ。
C++98/03 で safe bool イディオムを使っていたときは明示的に operator! を定義しないと駄目だった(はず)ですが、
explicit operator bool ではそんな手間をかけなくていいので、楽になったなあと感じた次第。
規格を読み直してみたところ、 C++98/03 であっても、
if の条件部に書けるならば問題なく ! 演算子のオペランドとして使えるようです。