52

[此问题与此问题相关但不同。]

如果我尝试使用某些类型的值作为布尔表达式,我会收到警告。?:我有时会使用三元运算符 ( ) 来转换为布尔值,而不是抑制警告。使用两个非运算符 ( !!) 似乎做同样的事情。

这就是我的意思:

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?

那么,双重不技术真的做同样的事情吗?它比三元技术更安全还是更安全?这种技术对于非整数类型(例如 withvoid *doublefor T)是否同样安全?

我不是在问是否!!t是好风格。我在问它是否在语义上不同于t ? true : false.

4

17 回答 17

84

的论点!运算符和三元运算符的第一个参数都隐式转换为布尔值,所以 !! 和?:是 IMO 愚蠢的演员阵容多余的装饰。我投票给

b = (t != 0);

没有隐式转换。

于 2008-10-15T20:07:30.010 回答
42

或者,您可以这样做:bool b = (t != 0)

于 2008-10-15T19:39:43.933 回答
32

小心!

  • 布尔值是关于真假。
  • 整数大约是整数。

这些是非常不同的概念:

  • 真与假是关于决定事物的。
  • 数字是关于计数的东西。

在桥接这些概念时,应该明确地完成。我最喜欢 Dima 的版本:

b = (t != 0);

该代码清楚地表明:比较两个数字并将真值存储在布尔值中。

于 2008-10-15T20:35:59.780 回答
6

所有有效的技术,都将生成相同的代码。

就个人而言,我只是禁用了警告,这样我就可以使用最简洁的语法。转换为 bool 并不是我担心会意外做的事情。

于 2008-10-15T19:38:41.520 回答
6


是的,它是安全的。


0 被解释为假,其他一切都为真,
因此 !5 为假
!0 为真
,所以 !!5 为真

于 2008-10-15T19:41:20.437 回答
6

我不会使用:

bool b = !!t;

这是最不可读的方式(因此最难维护)

其他的视情况而定。
如果您要转换为仅在布尔表达式中使用。

bool b = t ? true : false;
if (b)
{
    doSomething();
}

然后我会让语言为你做这件事:

if (t)
{
    doSomething();
}

如果您实际上存储的是布尔值。那么首先我想知道为什么你首先需要演员阵容。假设您需要 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.

总结:使用对你所处的环境最有意义的东西。
试着让你所做的事情变得显而易见

于 2008-10-15T20:10:42.623 回答
3

我建议永远不要抑制该警告,也不要使用 ac cast (bool) 来抑制它。转换可能并不总是像您假设的那样被调用。

计算结果为 true 的表达式和该值的布尔值之间存在差异。

两个都 !!并且 ternary 习惯了,但是如果你不想用重载类型转换为 bool 来定义内部类型,它们会以类似的方式完成工作。

Dima 的方法也很好,因为它将表达式的值分配给布尔值。

于 2008-10-15T19:45:54.843 回答
2

如果您担心警告,也可以强制转换:bool b = (bool)t;

于 2008-10-15T19:40:36.833 回答
2

我真的很讨厌!!t!!!!!!。它带有关于 C 和 C++ 最糟糕的东西的味道,即对你的语法过于聪明的诱惑。

布尔 b(t != 0); // 恕我直言,这是最好的方法,它明确显示正在发生的事情。

于 2008-10-15T21:08:59.370 回答
2

与 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
于 2018-05-25T06:39:53.023 回答
1

!!可能很紧凑,但我认为它不必要地复杂。在我看来,最好禁用警告或使用三元运算符。

于 2008-10-15T19:44:34.657 回答
0

我会使用 b = (0 != t) - 至少任何理智的人都可以轻松阅读它。如果我在代码中看到双重问题,我会非常惊讶。

于 2008-10-15T19:50:22.947 回答
0

禁用警告。

先写清楚;然后简介;然后在需要时优化速度。

于 2008-10-15T22:20:15.263 回答
0

!!仅当您以算术方式使用布尔表达式时才有用,例如:

c = 3 + !!extra; //3 or 4

(谁的风格是不同的讨论。)当你只需要一个布尔表达式时,!! 是多余的。写作

bool b = !!extra;

与以下内容一样有意义:

if (!!extra) { ... }
于 2008-10-15T23:58:14.240 回答
-1

我建议使用

如果 (x != 0)

或者

如果 (x != NULL)

而不是 if(x);它更易于理解和阅读。

于 2008-10-15T20:31:00.837 回答
-2

双重对我来说并不好笑,并且在调试代码中将与优化代码中的非常不同。

如果你爱上了!!你总是可以宏它。

#define LONGTOBOOL(x) (!!(x))

(顺便说一句,在这些情况下,我更喜欢三元运算符)

于 2008-10-15T19:45:53.407 回答
-4

我会使用 bool b = t 并留下编译警告,评论这一特定行的安全性。禁用警告可能会在代码的另一部分中咬你。

于 2008-10-15T20:25:00.943 回答