bVariable=!!iVariable vs.bVariable=(iVariable!=0) 我必须保持一个相当老的VisualC++源代码库。我发现这样的代码: bIsOk = !!m_ptr->isOpen(some Parameters)

bVariable=!!iVariable vs.bVariable=(iVariable!=0) 我必须保持一个相当老的VisualC++源代码库。我发现这样的代码: bIsOk = !!m_ptr->isOpen(some Parameters),c++,c,C++,C,bIsOk的数据类型是bool,isOpen(..)返回bool(定义为int) 工程师告诉我说这是从BOOL到BOOL最有效的方法 是这样吗?现在还在吗?2019年?我假设您指的是Win32 typeBOOL,这是一个typedef,用于int的历史C兼容性 规范化布尔值,将任何非零(即TRUE)值更改为1/TRUE。至于效率,这是很难解释的。规范化布尔值的其他方法(x | | 0,x&&1,(x!=0),等等)都应该由任何一个像样的编译器针对相同的问题进行优化 也就是说,如果规范化是显式需要

bIsOk
的数据类型是
bool
isOpen(..)
返回
bool
(定义为
int

工程师告诉我说这是从
BOOL
BOOL
最有效的方法


是这样吗?现在还在吗?2019年?

我假设您指的是Win32 type
BOOL
,这是一个
typedef
,用于
int
的历史C兼容性

规范化布尔值,将任何非零(即
TRUE
)值更改为1/
TRUE
。至于效率,这是很难解释的。规范化布尔值的其他方法(
x | | 0
x&&1
(x!=0)
,等等)都应该由任何一个像样的编译器针对相同的问题进行优化


也就是说,如果规范化是显式需要的,除非其目的是抑制编译器警告,否则不应该这样做。

考虑到您正在分配给
bool
,这样的转换已经由编译器隐式完成,因此“双重爆炸”在这里是无用的


如果您需要从表达式中的
BOOL
获取
BOOL
,那么“规范化”一个
BOOL
(或类似的东西)仍然很有用。在现代编译器上,我希望它生成与
!=0
,唯一的优点是它的输入更少(特别是考虑到一元
具有较高的优先级,而使用
!=
时,可能需要添加括号)

出现
的原因不是效率-任何像样的编译器都会将其编译成与任何其他非疯狂的转换方式完全相同的东西,包括仅仅依赖于隐式转换-但它抑制了一个关于“<代码> BoOL ”的隐式变窄,在VisualStudio的微软编译器的旧版本中出现,但在VS2017中被删除。

< P>,因此,在C++(和C)中,你可以隐式转换为<代码> BOOL (<代码>因此,您可以简单地编写

bIsOk = m_ptr->isOpen(some Parameters)
操作员
但是,请明确说明存在转换。它们相当于标准铸造
(bool)m_ptr->isOpen(某些参数)
m_ptr->isOpen(某些参数)=0
的唯一优点是因为它比强制转换的代码少

所有这些都产生完全相同的组件:

bVariable=!!iVariable vs.bVariable=(iVariable!=0)

您应该首先考虑可读性,让编译器生成高效的代码

如果您有这样的任务,只需将一个任务分配给另一个:

bVariable = iVariable;
<> >代码> int <代码> >代码>布尔O/COD>转换是很好定义的,任何C++程序员都应该是可读的。 如果需要转换变量或表达式,请使用适当的C++方法-<代码> STATICE-CASTE> <代码> < /P>
template<class T>
void foobar( T t );

foobar( static_cast<bool>( iVariable ) ); // explicitly let reader know that you changing type
模板
void-foobar(T);
foobar(静态_转换(可变));//明确地让读者知道您正在更改类型

<>代码>你编译代码为C++吗?至于“最有效的方法”,它取决于你所说的高效。就编写代码的字符数而言,它是有效的。虽然在我看来这真的不重要。就程序集大小或执行时间而言,您可以查看编译器将如何处理它,并将其与其他方法进行比较。我怀疑这会有什么区别。除非你每秒做数百万次这样的事情,否则对性能的影响基本上是零。您可能会将它们转换为字符串,base64编码,hex编码,然后使用字符串函数进行测试,它仍然会以荒谬的速度运行。@tadman甚至不会。生成的代码完全相同。@tadman我敢打赌,与表示强制转换的其他方式(包括不表示强制转换和依赖隐式强制转换)相比,在所有情况下,它都精确为零。因为程序集几乎肯定是相同的。请注意转换和强制转换之间的区别。强制转换是您在源代码中编写的命令编译器进行转换的内容。因此,不存在隐式转换。我编辑了答案,在适当的地方使用“转换”+1.@Pete Becker:谢谢。我把“隐式转换”改为“隐式转换”。没有所谓的隐式演员阵容。“转换”是指你在源代码中编写的命令编译器进行转换的代码。@PeteBecker:谢谢你的更正,尽管我对你第二句中的输入错误很感兴趣;当然,你在技术上是正确的。我没有看到打字错误。我错过了什么?这解释了很多。在代码库中消除警告一定是一条规则。它只是比!=0