定义双重感叹?

时间:2012-07-07 12:00:35

标签: c++ boolean logical-operators

我理解双重感叹号的作用(或者我认为我理解),但我不确定它是如何在随机对象上定义的。例如,在下面的代码段中:

Assignment *a;
if (!getAssignment(query, a))
   return false;
hasSolution = !!a;

if (!a)
   return true;

我如何知道双重感叹号会产生什么价值?换句话说,它总是转换为真?假?或者你能为它定义一个行为,比如执行一个方法来确定结果(对象如何知道在这种情况下如何行动)?由于所有这些感叹事件的发生,我对这段代码感到有点困惑。任何解释都表示赞赏。

希望我很清楚并感谢。

7 个答案:

答案 0 :(得分:17)

a是一个指针。在C ++中,nullptr被定义为无效指针。 !pointernullptr指针转换为true,将非nullptr指针转换为false!booleantrue变为false,将false变为true。它会一直有效。

!(!a)是一种有用的思考方式。

答案 1 :(得分:9)

不要将它视为“双重感叹号”,将其视为两个独立的运算符,一个运行于另一个运算符的结果。

对于所有原始类型,它将“起作用”。 !a相当于a == 0,因此!!a相当于!(a == 0),而a != 0相当于operator !

对于用户定义的类型,除非重载{{1}},否则不会编译。但显然,在这种情况下,行为几乎可以是任何事情。

答案 2 :(得分:4)

!!不是C ++中的单个令牌,只是解析为应用!运算符两次。

由于a是指针而不是类类型的对象,因此!不能重载。如果true是空指针,则定义为返回a,否则返回false

!的第二个应用只是否定了第一个!的结果。

表达式!!a相当于a != 0

答案 3 :(得分:3)

代码非常复杂。实际上,您希望测试getAssigment方法是否成功以及指定的指针是否为非空。

代码测试虽然是以复杂的方式利用弱类型,而不是试图接受显性和C ++的强类型。因此,它不是惯用的C ++,而是比必要的更难理解。

特别是,不要在C ++中使用!!a。这是弱类型语言(如JavaScript)中的既定惯用法,用于将值强制转换为布尔类型。但是在C ++中,这通常是

由于hasSolution未定义或使用,因此不清楚代码的作用。但是,我怀疑该代码应该等同于以下内容:

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

(在C ++ 11之前,您需要编写0而不是nullptr。)

但是,此代码仍然显示错误的设计:为什么a通过引用传递?为什么不是返回值?更糟糕的是,a从未使用过,所以没必要。如果确实不需要a,则应将其完全排除在外。如果有必要,它应该是返回值。换句话说,getAssignment的原型应该如下:

Assignment* getAssignment(the_type_of_query query);

它应该简单地使用如下:

Assignment* a = getAssignment(query);

此外,我怀疑此代码实际上将内存所有权分配给原始指针a。在现代C ++中,这是strongly discouraged。要么不使用指针,要么使用智能指针。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

没有" !!"运算符,所以实际上,该语句相当于:

hasSolution =!(!a);

首先,在表达式" a"上调用operator!(),然后在结果上调用另一个运算符!()。就我们的代码而言," a"是指向Assignement的指针。 C ++定义了一个在指针类型上使用operator!()的特殊情况:它返回一个bool,如果指针为null则为true,否则为false。简而言之,与表达式(a == 0)相同。在(!a)的结果上调用运算符!(),这是一个bool,只是恢复结果,即如果(!a)为假则返回true,如果(!a)为真则返回false。

总之,(!! a)返回与(a!= 0)相同的结果。这是因为" a"是一个指针。

答案 6 :(得分:0)

记住双重否定的最简单方法!! a是将a!= 0缩小到1,将a == 0缩小到0。 哪个在布尔上下文(即C ++)中为true或false。