是 !!在 C++ 中转换为 bool 的安全方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/206106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is !! a safe way to convert to bool in C++?
提问by jwfearn
[This question is related to but not the same as this one.]
[这个问题有关,但并不等同于这一个]
If I try to use values of certain types as boolean expressions, I get a warning. Rather than suppress the warning, I sometimes use the ternary operator (?:
) to convert to a bool. Using two not operators (!!
) seems to do the same thing.
如果我尝试将某些类型的值用作布尔表达式,则会收到警告。我有时会使用三元运算符 ( ?:
) 来转换为 bool ,而不是取消警告。使用两个非运算符 ( !!
) 似乎做同样的事情。
Here's what I mean:
这就是我的意思:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
So, does the double-not technique really do the same thing? Is it any more or less safe than the ternary technique? Is this technique equally safe with non-integral types (e.g., with void *
or double
for T
)?
那么,双重不技术真的能做同样的事情吗?它比三元技术更安全还是更不安全?这种技术对于非整数类型(例如 withvoid *
或double
for T
)是否同样安全?
I'm not asking if !!t
is good style. I am asking if it is semantically different than t ? true : false
.
我不是问是否!!t
是好的风格。我在问它在语义上是否与t ? true : false
.
回答by fizzer
The argument of the ! operator and the first argument of the ternary operator are both implicitly converted to bool, so !! and ?: are IMO silly redundant decorations of the cast. I vote for
的论点!运算符和三元运算符的第一个参数都隐式转换为 bool,所以 !! 和?:IMO 是演员的愚蠢的多余装饰。我投赞成票
b = (t != 0);
No implicit conversions.
没有隐式转换。
回答by Dima
Alternatively, you can do this: bool b = (t != 0)
或者,您可以这样做: bool b = (t != 0)
回答by edgar.holleis
Careful!
小心!
- A boolean is about truth and falseness.
- An integer is about whole numbers.
- 布尔值是关于真假的。
- 整数是关于整数。
Those are very distinct concepts:
这些是非常不同的概念:
- Truth and falseness is about deciding stuff.
- Numbers are about counting stuff.
- 真假是关于决定事物的。
- 数字是关于计算东西的。
When bridging those concepts, it should be done explicitly. I like Dima's version best:
在桥接这些概念时,应该明确地完成。我最喜欢 Dima 的版本:
b = (t != 0);
b = (t != 0);
That code clearly says: Compare two numbers and store the truth-value in a boolean.
该代码清楚地表明:比较两个数字并将真值存储在布尔值中。
回答by Martin York
I would not use:
我不会使用:
bool b = !!t;
That is the least readable way (and thus the hardest to maintain)
这是最不可读的方式(因此最难维护)
The others depend on the situation.
If you are converting to use in a bool expression only.
其他视情况而定。
如果您要转换为仅在 bool 表达式中使用。
bool b = t ? true : false;
if (b)
{
doSomething();
}
Then I would let the language do it for you:
然后我会让语言为你做这件事:
if (t)
{
doSomething();
}
If you are actually storing a boolean value. Then first I would wonder why you have a long in the first places that requires the cast. Assuming you need the long and the bool value I would consider all the following depending on the situation.
如果您实际存储的是布尔值。那么首先我想知道为什么你有一个需要演员表的地方。假设您需要 long 和 bool 值,我会根据情况考虑以下所有内容。
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
Summary:
Use what provides the most meaning for the context you are in.
Try and make it obvious what you are doing
总结:使用对你所处的上下文最有意义的东西。
试着让你所做的事情变得显而易见
回答by Martin York
All valid techniques, all will generate the same code.
所有有效的技术,都会生成相同的代码。
Personally, I just disable the warning so I can use the cleanest syntax. Casting to a bool is not something I'm worried about doing accidentally.
就我个人而言,我只是禁用警告,这样我就可以使用最干净的语法。强制转换为 bool 并不是我担心不小心做的事情。
回答by EvilTeach
Yes it is safe.
是的,它是安全的。
0 is interpreted as false, everthing else is true,
hence !5 comes out as a false
!0 comes out as true
so !!5 comes out as true
0 被解释为假,其他一切都是真的,
因此 !5 为假
!0 为真,
所以 !!5 为真
回答by tabdamage
I recommend never suppressing that warning, and never using a c cast (bool) to suppress it. The conversions may not always be called as you assume.
我建议永远不要抑制该警告,也永远不要使用 ac cast (bool) 来抑制它。转换可能并不总是像您假设的那样被调用。
There is a difference between an expression that evaluates to true and a boolean of that value.
计算结果为 true 的表达式和该值的布尔值之间存在差异。
Both !! and ternary take getting used to, but will do the job similarly, if you do not want to define internal types with overloaded casts to bool.
两个都 !!和三元需要习惯,但如果您不想定义具有重载强制转换为 bool 的内部类型,则可以类似地完成这项工作。
Dima's approach is fine too, since it assigns the value of an expression to a bool.
Dima 的方法也很好,因为它将表达式的值分配给 bool。
回答by warren
If you're worried about the warning, you can also force the cast: bool b = (bool)t;
如果您担心警告,您还可以强制转换: bool b = (bool)t;
回答by Jim In Texas
I really hate !!t!!!!!!. It smacks of the worst thing about C and C++, the temptation to be too clever by half with your syntax.
我真的很讨厌!!t!!!!!!. 它有点像 C 和 C++ 最糟糕的事情,诱惑你的语法太聪明了一半。
bool b(t != 0); // Is the best way IMHO, it explicitly shows what is happening.
bool b(t != 0); // 恕我直言,这是最好的方式,它明确地显示了正在发生的事情。
回答by Jay K
Comparison to 0 doesn't work so well. Which comes back -- why !! vs. ternary?
与 0 的比较效果不佳。又回来了——为什么!!与三元?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok