我如何将BOOL转换为BOOL?

<windows.h>标题带有自己的BOOLtypes。 在实现中偷看,看起来FALSE只是一个0的macros,而TRUE只是一个macros,但我不确定这是否被指定。

什么是将BOOL转换为BOOL的惯用方法? 我可以想像很多可能的方法:

 bool a = static_cast<bool>(x); bool b = x ? true : false; bool c = (x == TRUE); bool d = (x != FALSE); bool e = !!x; // ... 

不需要任何明确的转换:

 BOOL x = some_value; bool b = x; 

将数值类型隐式转换为bool将为0值为false ,对于任何非零值则为true

顺便提一句,你告诉我们<windows.h>如何定义FALSETRUE 。 它如何定义BOOL ? (从你的评论,这是typedef int BOOL;

但是一些编译器可能会警告这种隐式转换,即使它是完全有效的代码。 编译器可以自由地警告任何他们喜欢的东西,包括用来编写代码的难看的字体。 例如,g ++不会抱怨转换,即使是:

 g++ -std=c++11 -pedantic -Wall -Wextra ... 

但是根据这个在线Visual C ++编译器 ,VC ++确实会产生一个警告:

 warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) 

即使使用static_cast ,它仍然会产生警告。

你可以通过使用!!xx ? true : false来避免这个警告x ? true : false x ? true : false 。 但我不确定治愈好于疾病。

做到这一点的简单而正确的方法是简单地分配值,并依靠隐式转换来做正确的事情(它会)。

如果您有额外的要求来避免编译器警告,那么这成为更多关于Visual C ++而不是C ++语言的问题。 在不改变源头的情况下,也可能有某种方法来禁止某些警告 – 尽管这样做有可能在实际上有意义时丢失相同的警告。 DieterLücking在评论中建议:

 #pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning) 

但看起来还是需要修改源代码。 也许有一些相同的东西没有。

还有一件事:由于BOOL实际上是int类型,所以这个建议的解决方案是:

 bool c = (x == TRUE); 

并不等同于其他人。 任何非零int都被视为true,但只有值1 等于 TRUE 。 例如,如果x == 2 ,则上面的将c设置为false ,而if (x)仍然会将其视为真实条件。 切勿将布尔值的相等性与trueTRUE 。 (比较它们为falseFALSE更安全,但仍然不必要;这就是!运算符的用途。)

这一切都假设,如果你有一个BOOL类型的值,你只关心它是真的还是真的(零或非零)。 不幸的是,情况并非总是如此。 Ben Voight的回答指出,微软的API至少包含一个函数GetMessage ,它返回的BOOL结果不是一个简单的布尔值。 在这种可怕的情况下,如果您需要区分多个非零值,则从BOOLbool转换并不合适。

最后,我责怪微软为已经具有完美表现的内置bool类型的语言定义了BOOL类型。 其实这不太公平, 它用于需要从C和C ++访问的API。 微软对BOOL的定义可能会回到他们的C语言实现上,这在某种程度上是有道理的 – 至少在C99之前,微软仍然不支持。 (我不知道微软的C编译器是否支持_Bool ,即使是这样, _Boolint有一些语义上的区别,改变BOOL的定义可能会破坏一些代码 – 尤其是使用GetMessage代码。

我使用一个宏:

 #define _bool(b) (!!(b)) 

海事组织,使我的代码更具可读性。

编辑:一位评论者质疑我在宏名称中使用下划线。 为了解决这个问题,这是一个新的版本,仍然是通用的,仍然使用相同的名称_bool ,但是是符合的,据此。

 namespace MyBool { template<typename T> inline bool _bool(const T b) { return !!b; } } using namespace MyBool; 

很难说win32程序员怎么做,但恕我直言,它应该通过:

 bool c = (X == TRUE); 

要么

 bool d = (x != FALSE); 

我认为这是一个不错的做法,在宏(或任何其他预定义的东西)
恒定。

有一天TRUE可能变成0和FALSE 1;)

没有安全的方法,因为Win32 BOOL有两个以上的值 。

这是一个有点意见的问题,但是我认为有很多客观的论点可供选择。

最好的选择是:

 bool d = (x != FALSE); 

这使得读者的意图非常清楚,不依赖于隐式转换,并且明确表示除了一个简单的赋值之外还有更多的工作要做。

第二个最好的选择是:

 bool b = x ? true : false; 

但是,对于不经意的读者来说,这看起来像是一个同义反复。

我尝试避免在作业中进行隐式转换,因为获取错误的转换是令人惊讶的错误来源。 即使当我知道隐式转换会做正确的事情时,我倾向于明确地做,这可能有助于有人在将来阅读代码。 明确还允许您保持启用转换警告,以便捕获您不知道您(ab)使用的其他隐式转换。

替代品都有更严重的缺陷。

 bool a = static_cast<bool>(x); 

这就像锤击一个方形的钉子进入一个圆孔。 编写一个自然而然地返回正确类型的表达式会更加优雅。

 bool c = (x == TRUE); 

TRUE进行比较通常是一个坏主意,因为其他非零值将转换为false,这几乎肯定是一个错误。

 bool e = !!x; 

太聪明了,相比之下,表达你的意思。 (我过去犯了这个罪。)

 bool f = x; 

MSVC ++对纯隐式转换的性能警告似乎是公平的。 编译器必须生成额外的代码来将int转换为bool。 对于这项额外​​的工作,这份空白的任务毫无头绪。 如果它在一个紧密的循环,你可能会在意。 (当然, static_cast选项中的性能警告看起来太过分了,但是我们已经认定这样做不够优雅了。)

db表达清楚地表达了意图,并且明显地表明在这里比直接指派更多。