我如何习惯性地将BOOL转换为bool?

fre*_*low 8 c++ windows winapi boolean type-conversion

<windows.h>头带有自己的BOOL类型.窥视实现,它似乎FALSE只是一个宏0,并且TRUE只是一个宏1,但我不确定这是否已指定.

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

bool a = static_cast<bool>(x);

bool b = x ? true : false;

bool c = (x == TRUE);

bool d = (x != FALSE);

bool e = !!x;

// ...
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 7

无需任何明确的转换:

BOOL x = some_value;
bool b = x;
Run Code Online (Sandbox Code Playgroud)

数字类型的隐式转换bool的产量false为的值0,并且true对于任何非零值.

顺便说一句,你已经告诉我们如何<windows.h>定义FALSETRUE.它是如何定义的BOOL?(根据你的评论,它是typedef int BOOL;)

但是一些编译器可能会警告这种隐式转换,即使它是完全有效的代码.编译器可以随意警告他们喜欢的任何内容,包括用于编写代码的丑陋字体.例如,g ++不会抱怨转换,即使:

g++ -std=c++11 -pedantic -Wall -Wextra ...
Run Code Online (Sandbox Code Playgroud)

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

warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
Run Code Online (Sandbox Code Playgroud)

即使有了static_cast,它仍会产生警告.

您可以使用!!x或来避免警告x ? true : false.但我不确定治愈方法是否比疾病更好.

这样做的简单而正确的方法就是分配值并依靠隐式转换来做正确的事情(它会).

如果你有一个额外的要求来避免编译器警告,那么这就变成了一个关于Visual C++而不是C++语言的问题.可能还有某种方法可以在不改变来源的情况下禁止某些警告 - 尽管当它们真正有意义时可能会失去同样的警告.在评论中,DieterLücking建议:

#pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning)
Run Code Online (Sandbox Code Playgroud)

但看起来它仍然需要修改源.也许有一些不相同的东西.

还有一件事:既然BOOL是真正的类型int,这个提议的解决方案:

bool c = (x == TRUE);
Run Code Online (Sandbox Code Playgroud)

不等于其他人.任何非零int被当作真实的,但只有值1等于TRUE.以上将设置cfalse如果x == 2,例如-而if (x)仍然把它作为一个真正的条件.永远不要将相等的布尔值与true或进行比较TRUE.(将它们比较falseFALSE更安全,但仍然没有必要;这就是!运营商的用途.)

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

最终,我责怪微软为一种BOOL已经具有完美表现的内置类型的语言定义一种bool类型.实际上这不太公平; 它用在需要从C和C++访问的API中.微软的定义BOOL可能会回到他们的C实现,它有一定意义 - 至少在C99之前,微软仍然不支持.(我不知道微软的C编译器是否支持_Bool.即使它确实存在,_Bool也有一些语义差异int,并且改变定义BOOL可能会破坏某些代码 - 特别是使用的代码GetMessage.)

  • 这给了我一个编译器警告.否则我不会问:) (2认同)