次のコードを検討してください。
class Truth
{
public:
Truth(bool val) : value(val) {}
bool operator!() {std::cout<<"operator!()"<<std::endl; return !value;}
operator bool() {std::cout<<"operator bool()"<<std::endl; return value;}
private:
bool value;
};
int main()
{
Truth t(true);
if(!t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
if(!!t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
if(t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
return 0;
}
ステートメントif(!t)
でif(!!t)
は、オーバーロードされたoperator!()
実装が呼び出されますが、(驚くべきことではありませんが) ステートメントでは、代わりにif(t)
オーバーロードされたoperator bool()
実装が呼び出されます。
ただし、operator!()
実装がコメントアウトされている場合は、3 つのステートメントすべてでoperator bool()
呼び出されます。
これが発生する「理由」は理解していますが、私の懸念は、論理 NOT 演算子 (!) をオーバーロードすると、真偽評価のセマンティクスの半分が失われているように見えますが、bool
型キャスト演算子はそれらをうまくカバーしているように見えます。
何か不足していますか、それともブール型キャストを優先して論理 NOT 演算子のオーバーロードをやめるべきですか?