Defining double exclamation?

女生的网名这么多〃 提交于 2019-12-03 03:12:56

a is a pointer. In C++, nullptr is defined to be an invalid pointer. !pointer turns a nullptr pointer into true and a non nullptr pointer into false. !boolean turns true into false and false into true. It will always work.

!(!a) is a useful way to think of it.

Don't think of it as "double exclamation mark", think of it as two separate operators, one running on the result of the other.

For all primitive types, it will "work". !a is equivalent to a == 0, so !!a is equivalent to !(a == 0), which in turn is equivalent to a != 0.

For user-defined types, it won't compile unless they overload operator !. But obviously, in this case, the behaviour could be almost anything.

!! is not a single token in C++ and simply resolves to applying the ! operator twice.

As a is a pointer and not an object of class type the ! cannot be overloaded. It is defined to return true if a is a null pointer and false otherwise.

The second application of ! simply negates the result of the first !.

The expression !!a is equivalent to a != 0.

The code is horribly complicated. In reality, you want to test whether the getAssigment method is successful and whether the assigned pointer is non-null.

The code tests that, albeit in a convoluted fashion, taking advantage of weak typing, rather than trying to embrace explicitness and C++’ strong typing. As a consequence, it’s not idiomatic C++ and rather harder to understand than necessary.

In particular, don’t use !!a in C++. This is an established idiom in weakly-typed languages such as JavaScript to coerce a value into a boolean type. But in C++, this is not commonly used.

It’s not clear what the code does since hasSolution isn’t defined or used. However, I suspect that the code is supposed to be equivalent to the following:

Assignment *a;
return getAssignment(query, a) and a == nullptr;

(Before C++11, you need to write 0 instead of nullptr.)

However, this code still reveals a bad design: why is a passed by reference? Why isn’t it the return value? Worse, a is never used, so unnecessary. If a is indeed unnecessary, it should be left out completely. If it’s necessary, it should be the return value. In other words, the prototype of getAssignment should be as follows:

Assignment* getAssignment(the_type_of_query query);

And it should be used simply as follows:

Assignment* a = getAssignment(query);

Furthermore, I suspect that this code actually assigns memory ownership to the raw pointer a. This is strongly discouraged in modern C++. Either use no pointers or a smart pointer.

bool result = true; 
result = !!result; // result = true, e.g. !result is false, !!result is !false.

There is no "!!" operator, so in fact, the statement is equivalent to:

hasSolution = !(!a);

So first, operator!() is called on expression "a", then another operator!() is called on the result. In the case of our code, "a" is a pointer to Assignement. C++ defines a special case for using operator!() on a pointer type: it returns a bool which is true if the pointer is null and false otherwise. In short, the same as the expression (a == 0). Calling operator!() on the result of (!a), which is a bool, simply reverts the result, i.e. returns true if (!a) is false and false if (!a) is true.

So in conclusion, (!!a) return the same result as (a != 0). This is because "a" is a pointer.

The easiest way to remember double-negation !!a is to narrow a!=0 to 1 and a==0 to 0. Which is in boolean context (i.e. C++) true or false.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!