简体   繁体   中英

C++ !! conversion to bool

In C++ there is a construction !! applicable to non bool values to convert it to bool. For instance:

int n = 12;

if ( !!n )
  std::<<cout << "n is true";
else
  std::<<cout << "n is false";

Is there any restrictions where it can be applied, or which types is applicable: POD, pointers, etc.?

The restriction is that operator! must be defined for the type (and it must yield a type for which operator! is also defined)

It works for any type that can be evaluated in a boolean context. So arithmetic types, pointer types (including pointer-to-(member)(function)), and anything with a conversion to one of those. Plus odds and ends like enum types, std::nullptr_t , and probably something else I've forgotten. 4/3 in C++11 defines what contextually converted to bool means, and that's what the built-in operator! does.

For all of these types, writing if(!!n) is redundant, you can write if(n) with the same meaning. !!n for such types means the same as bool(n) or static_cast<bool>(n); .

It also works for any type with an overloaded operator! that returns a type that can be converted to bool (or that returns a type with operator! overloaded to return bool ).

If the leftmost operator! returns a type other than bool, then you might still be able to write if(!!n) , but !! doesn't act as a conversion to bool . It acts as a conversion to whatever type is returned.

The other answers are good for your actual question.

However, just in case you were planning to use the code in your example to "simplify" your code (in that it makes the code shorter) I thought I would suggest that you don't do that. Rather, simplify the meaning and check the integer for zero rather than a double negative on an integer.

if (n!=0) 
    { 
      //whatever
    }

Explicitly testing against zero has the benefit of being independent as to whether you remember the "zero is false" convention used in c++. See https://stackoverflow.com/q/329582/498253 , and the comments below.

This is because for me, if(!!my_int) is not very clear - its not obvious what is meant to happen, and to form a branch at this point looks like its going to cause problems.

Previous snippet (so that the very useful comments make sense)

bool my_bool = (n != 0) ? true : false; //whichever way you want it to work.
if (my_bool) 
  { 
    //whatever
  }

The only restriction is that the object of the certain type should be convertible to bool or integer type.

For example, next type can not be converted :

struct A
{
  int a;
  float b;
};

but next can :

struct B
{
  int v;
  operator int()
  {
    return v;
  }
};

!! is simply the ! operator applied twice. It is applicable to all expressions where ! can be used.

Edit:

Overloaded instances of operator ! are assumed to be implemented as logical not .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM