使用双重逻辑非(!!)运算符感到困惑[重复]
Posted
技术标签:
【中文标题】使用双重逻辑非(!!)运算符感到困惑[重复]【英文标题】:Confused by use of double logical not (!!) operator [duplicate] 【发布时间】:2013-04-17 23:19:42 【问题描述】:我有一些广泛使用!!
的C++ 代码。我有点困惑,因为据我所知,!!
本身并不是一个操作员,而是两个!
一个接一个。这意味着!!foo
与foo
相同。
!!
有什么地方和理由吗?我在想它是否可能有一点明智的意义?因此,您首先对foo
执行一些位操作,然后对结果执行!
?但我似乎不记得!
被用作有点明智的运算符,并且似乎也没有找到任何参考告诉我它是。据我所知,!
仅用作逻辑运算符,在这种情况下
!!foo == foo
【问题讨论】:
也可以写x+++++y+1
,但这是个坏主意。
@GrahamBorland 现在我要去那里投票,作为这个的副本。
您可能还想阅读这篇文章:what is !! in c?.
@msw 不,你不能。在两个序列点之间多次修改是未定义的行为。 !!
定义完美,对应触发安全布尔转换运算符。这对于optional
、variant
或任何智能指针特别有用。
【参考方案1】:
它可以用作将foo
转换为布尔表达式的速记。出于某种原因,您可能只想将非布尔表达式转换为 true 或 false。
foo = !!foo
将把foo
变成1
如果它不为零,如果它已经是,则将它留在0
。
【讨论】:
【参考方案2】:此技术用于在布尔上下文中对变量进行安全评估。如果您与布尔(operator bool()
)进行正常对话,则不相关的变量(具有不同类型)可能会以不需要的方式参与布尔表达式。实现了返回否定布尔值的operator!
定义。它的结果必须再次被否定。只需看看Safe bool idiom。
【讨论】:
【参考方案3】:这不是双重否定那么简单。例如,如果您有x == 5
,则应用两个!运算符(!!x
),它将变为 1 - 因此,它用于规范化 0, 1
范围内的布尔值。
请注意,您可以将零用作布尔值 false,将非零值用作布尔值 true,但您可能需要将结果标准化为 0 或 1,此时 !!
很有用。
与x != 0 ? 1 : 0
相同。
另外,请注意,如果foo
不在0, 1
集合中,这将不正确:
!!foo == foo
#include <iostream>
using namespace std;
int main()
int foo = 5;
if(foo == !!foo)
cout << "foo == !!foo" << endl;
else
cout << "foo != !!foo" << endl;
return 0;
打印foo != !!foo
。
【讨论】:
可能的用例是什么? 假设您在某个地方将 bool 存储为 1 或 0,以位或其他形式存储。你检查的值是 5(这会被认为是真的),你基本上可以把 5 变成 1。 布尔 x = !0; // true bool x = !-15 // false int i = x;看看这个 更正式一点,它的结果是true
。 bool
类型的值为 true
和 false
。在算术上下文中,它们分别转换为 1
和 0
。
我在编译器上使用了这种技术,当我将int
隐式转换为bool
(性能警告:值将被转换为 0 或 1)时,该编译器会报错。我的选择是做一个 C 风格的 bool
演员表(我认为这是一个坏习惯),做 0 != v
(之后的 ?1:0
是多余的)这会造成操作顺序的模糊性迫使 ()
ing (在至少要弄清楚发生了什么),或static_cast<bool>( v )
过于冗长。 !!
将可隐式转换为 bool
的类型转换为 bool
而不会发出警告并作为一元(因此是紧密绑定的)运算符。【参考方案4】:
如果foo
不是bool 类型,那么!!foo
将是。所以!!foo
可以是 1 或 0。
【讨论】:
0
和 1
是 int
s,而不是 bool
s。我们在这里谈论的是 C++;也许你把它和 C 混淆了?
你是对的。我应该说真假。 :)【参考方案5】:
如果foo != 0
,那么!!foo == 1
。转换为 bool 基本上是一个技巧。
【讨论】:
1
不是bool
。这是int
。
@Kerrek SB 我知道,我指的是实际值。以上是关于使用双重逻辑非(!!)运算符感到困惑[重复]的主要内容,如果未能解决你的问题,请参考以下文章