为什么使用! 当转换为BOOL BOOL?

以这种方式将整数转换为布尔值的原因是什么?

bool booleanValue = !!integerValue; 

而不是仅仅

 bool booleanValue = integerValue; 

我所知道的是在VC ++ 7中,后者将导致C4800警告 ,而前者不会。 两者之间还有其他的区别吗?

与“!!”的问题 成语是它很简单,很难看,很容易误以为是一个错字,容易掉一个“!”,等等。 我把它放在“看看我们可以用C / C ++多么可爱”的类别中。

只要写bool isNonZero = (integerValue != 0); … 清楚。

历史上, !! 成语是用来确保你的bool确实包含了bool likevariables中预期的两个值之一,因为C和C ++没有真正的booltypes,我们用int伪造它。 与“真正的” bool现在这是一个问题。

但使用!! 是一个有效的方法来logging(对于编译器和任何未来在你的代码中工作的人)是的,你确实打算把这个int bool一个bool

因为!integerValue表示integerValue == 0而!! integerValue因此意味着integerValue!= 0,这是一个返回一个bool的有效expression式。 后者是一个信息丢失的演员。

这是因为C语言(和一些预标准的C ++编译器)也没有booltypes,只是int 。 所以int被用来表示逻辑值: 0应该是false ,其他的都是true 。 那! 运算符从00返回1 。 双重! 被用来反转这些,并在那里确定这个值只是01这取决于它的逻辑值。

在C ++中,由于引入了适当的booltypes,因此不再需要这样做。 但是你不能只更新所有的遗留源,而且你不应该因为C和C ++的向后兼容(大部分时间)。 但是许多人仍然这样做,出于同样的原因:保持自己的代码向后兼容那些仍然不懂bool的旧编译器。

这是唯一真正的答案。 其他答案是误导。

另一种select是三元运算符似乎生成一行less汇编代码(无论在Visual Studio 2005中):

 bool ternary_test = ( int_val == 0 ) ? false : true; 

这会产生汇编代码:

 cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _ternary_test$[ebp], al 

与:

 bool not_equal_test = ( int_val != 0 ); 

这产生:

 xor eax, eax cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _not_equal_test$[ebp], al 

我知道这不是一个巨大的差异,但我很好奇,只是想我会分享我的发现。

一个布尔只能有两个状态,0和1.一个整数可以有一个从-2147483648到2147483647的任何状态,假设一个有符号的32位整数。 一元! 如果input为0,则操作员输出1,如果input是除0之外的任何其他输出,则输出0。因此!0 = 1且!234 = 0。 只需切换输出,使0变成1,1变成0。

所以第一个语句保证布尔值将被设置为等于0或1而不是其他值,第二个语句不会。

!! 是一种转换为bool的惯用方式,它可以阻止Visual C ++编译器对这种转换的低效率的愚蠢警告。

我从其他答案和评论中看到很多人不熟悉这个习语在Windows编程中的用处。 这意味着他们没有做任何严肃的Windows编程。 盲目地假设他们遇到的是有代表性的(不是)。

 #include <iostream> using namespace std; int main( int argc, char* argv[] ) { bool const b = static_cast< bool >( argc ); (void) argv; (void) b; } 
 > [d:\ dev \ test]
 > cl foo.cpp
 Foo.cpp中
 foo.cpp(6):警告C4800:'int':强制值为bool'true'或'false'(性能警告)

 [d:\ dev的\testing]
 > _

至less有一个人认为,如果一个新手不认识它的意思,那么它就是不好的。 那真是愚蠢。 新手不认识或理解的东西有很多。 编写一个代码,以便任何新手都能理解它,这对于专业人员来说并不是什么东西。 甚至没有学生。 从排除新手无法识别的操作符和操作符组合的path开始……那么我没有给出这种方法的适当描述的话,对不起。

干杯&hth。,

没有什么大的理由,除了是偏执狂或通过代码,它是一个布尔大喊大叫。

对于编译器来说,它不会有所作为。

我从来不喜欢这种转换为bool数据types的技术 – 它的味道是错误的!

相反,我们在这里使用了一个名为boolean_cast的方便模板。 这是一个灵活的解决scheme,它在做什么更明确,可以使用如下:

 bool IsWindow = boolean_cast< bool >(::IsWindow(hWnd));