🤡

ちょっとひねった論理否定オペレータ

に公開

C++で以下のようなコードを見たことありますか?

int data_size = 5;
bool data_not_empty = !!data_size;  // !!

!!」というオペレータはないので、論理否定オペレータ「 ! 」を2回使っていることになります。
でも論理否定オペレーターを2回使うと、元の値が返るだけなので、使う意味がないのではないでしょうか?

!」オペレータはbool型だけではなく、どの算術型にも使えますが、bool型の戻り値を返します。実質は以下のような実装になっているはずです。

template <typename T>
bool operator!(const T& a)
{
    return a == 0;
}

そのため、「!!」はbool型への変換に使えます。以下のコードは全部同じ結果になります。

int data_size = 5;
bool data_not_empty = !!data_size;
bool data_not_empty = data_size;
bool data_not_empty = data_size ? true : false;
bool data_not_empty = data_size != 0;
bool data_not_empty = bool(data_size);
bool data_not_empty = static_cast<bool>(data_size);

でも上記の場合は、三項演算子とdata_size != 0が一番分かりやすくてお勧めです。

!!がよく使われるのは、以下のようなbool型へ暗黙的に変換されない型を変換させる、という特殊なケースです。

auto data(std::make_unique<int>(5));
const bool data_not_null = data; // no viable conversion というエラーになります。
const bool data_not_null = !!data; // OK

std::optionalstd::variantでも同じことができます。

しかし、「!!」を初めて見る人は恐らく困惑すると思うので、あんまり使うことをお勧めできないです。
やはり以下のような書き方が一番分かりやすいと思います。

const bool data_not_null = (data != nullptr);

でも「!!」はたまに見かけるので、知っておくといいかもしれません。


|cpp記事一覧へのリンク|

Discussion