How does the unary minus operator work on booleans in C++?

前端 未结 4 1065
别跟我提以往
别跟我提以往 2021-01-19 00:55

I am currently converting some OpenCV code from C++ to Java. I can\'t use JavaCV, as we need the conversion in native Java, not a JNA. At one point in the code, I get the fo

相关标签:
4条回答
  • 2021-01-19 00:57

    What it basically does is following:

    kHit >= kForeground
    

    is an expression of type bool

    -(kHit >= kForeground)
    

    converts this bool into an int (based on true==1 and false==0) and negates it, which results in true==-1 and false==0.

    This is then converted into a uchar, which results in -1==255 and 0==0.

    It has to be noted that though seeming as using the underlying implementation details of the numbers, all those conversions are guaranteed by the C++ and C standards, as negative unsigned numbers are specified to behave according to twos-complement.

    But if Java doesn't support this, you can always replace it by a conditional assignment:

    dst[x] = (kHit>=kForeground) ? 255 : 0;
    
    0 讨论(0)
  • 2021-01-19 01:07

    In C++ a boolean expression produces one of two values - 0 or 1. When you apply the unary minus - to the result, you get 0 or -1. When you re-interpret -1 as uchar, you get 255.

    You can convert this expression to Java with a conditional:

    dst[x] = (kHit >= kForeground) ? 255 : 0;
    

    Because of branching, it is not going to be as fast as the original one. There's little you can do about the speed of it, however, as Java lacks abilities to re-interpret boolean values as numerics.

    0 讨论(0)
  • 2021-01-19 01:18

    kHit >= kForeground returns either true or false, which in C++ sort of means 1 or 0. The minus in front transforms this to -1 or 0. The cast to uchar ((uchar)) returns 0 for 0 and wraps to 255 for the negative -1.

    Following Konrad's comment, I'm also skeptical this is well defined. It is well defined, but it's still an awful piece of code in terms of readability. :)

    0 讨论(0)
  • 2021-01-19 01:20

    The expression (kHit >= kForeground) yields a boolean that has value true or false. When the unary - is applied, the bool gets promoted to an int, and the conversion yields 1 for true or 0 for false. After the promotion, the sign is changed into -1 or 0 and then it is converted to uchar by the outer cast.

    Note that the important bit of information is that the unary operator- is not applied to a boolean, but the boolean is converted to int and it is then applied. That can be tested with a bit of template magic:

    template <typename T, typename U>
    struct same_type {
        static const bool value = false;
    };
    template <typename T>
    struct same_type<T,T> {
        static const bool value = true;
    };
    template <typename T>
    void f( T value ) {
        std::cout << "Is int? " << std::boolalpha << same_type<T, int>::value << "\n";
        std::cout << "Is bool? " << same_type<T, bool>::value << "\n";
    }
    int main() {
        f(-true);
    }
    

    The f template tests the type of the passed argument against int and bool by using the same_type templates above (trivial enough to understand). If we call the f template with -true as argument type deduction will set T to be the type of the expression -true. If you run the program, you will see that it prints Is int? true\nIs bool? false.

    0 讨论(0)
提交回复
热议问题