是! !在c++中转换为bool的安全方法?

时间:2021-04-25 22:46:56

[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,而不是抑制警告。使用两个not运算符(!!)似乎也做同样的事情。

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)?

那么,double-not技术真的做同样的事情吗?它比三元技术更安全吗?这种技术是否同样适用于非整数类型(例如,用void *或double来表示T)?

I'm not asking if !!t is good style. I am asking if it is semantically different than t ? true : false.

我不是在问!!t是好的风格。我问它是否和t有语义上的不同?真的,假的。

16 个解决方案

#1


83  

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,所以!!还有?:这些都是演员们愚蠢的多余装饰。我投票给

b = (t != 0);

No implicit conversions.

没有隐式转换。

#2


41  

Alternatively, you can do this: bool b = (t != 0)

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

#3


31  

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.

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

#4


6  

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。

#5


6  


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出来是真的!!结果是正确的。

#6


5  

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

总结:使用对你所处的环境最有意义的东西。试着让它明显地表明你在做什么。

#7


3  

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.

我建议永远不要压制这个警告,不要使用c 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.

两个! !ternary需要习惯,但也会做类似的工作,如果你不想定义内部类型,那么就会有重载的类型转换到bool。

Dima's approach is fine too, since it assigns the value of an expression to a bool.

Dima的方法也很好,因为它将表达式的值赋给了bool。

#8


2  

If you're worried about the warning, you can also force the cast: bool b = (bool)t;

如果你担心这个警告,你也可以强迫演员:bool b = (bool)t;

#9


2  

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);//是IMHO最好的方式,它明确显示了正在发生的事情。

#10


1  

!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.

! !可能是紧凑的,但我认为这是不必要的复杂。在我看来,最好是禁用警告或使用三元操作符。

#11


0  

I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.

我要用b = (0 != t)——至少任何一个理智的人都能很容易地读懂。如果在代码中看到双党,我会非常惊讶。

#12


0  

Disable the warning.

禁用警告。

Write for clarity first; then profile; then optimize for speed, where required.

写清楚;然后概要;然后在需要的地方优化速度。

#13


0  

!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:

! !只有在使用算术方式的布尔表达式时才有用,例如:

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

(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing

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

bool b = !!extra;

makes as much sense as:

就像:

if (!!extra) { ... }

#14


-1  

The double not feels funny to me and in debug code will be very different than in optimized code.

在我和调试代码中,双重的感觉不是很有趣,它与优化后的代码非常不同。

If you're in love with !! you could always Macro it.

如果你爱上了!!你可以把它放大。

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

(as an aside, the ternary operator is what I favor in these cases)

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

#15


-1  

I recommend to use

我推荐使用

if (x != 0)

如果(x ! = 0)

or

if (x != NULL)

如果(x ! = NULL)

instead of if(x); it's more understandable and readable.

而如果(x);它更易于理解和可读性。

#16


-4  

I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.

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

#1


83  

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,所以!!还有?:这些都是演员们愚蠢的多余装饰。我投票给

b = (t != 0);

No implicit conversions.

没有隐式转换。

#2


41  

Alternatively, you can do this: bool b = (t != 0)

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

#3


31  

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.

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

#4


6  

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。

#5


6  


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出来是真的!!结果是正确的。

#6


5  

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

总结:使用对你所处的环境最有意义的东西。试着让它明显地表明你在做什么。

#7


3  

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.

我建议永远不要压制这个警告,不要使用c 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.

两个! !ternary需要习惯,但也会做类似的工作,如果你不想定义内部类型,那么就会有重载的类型转换到bool。

Dima's approach is fine too, since it assigns the value of an expression to a bool.

Dima的方法也很好,因为它将表达式的值赋给了bool。

#8


2  

If you're worried about the warning, you can also force the cast: bool b = (bool)t;

如果你担心这个警告,你也可以强迫演员:bool b = (bool)t;

#9


2  

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);//是IMHO最好的方式,它明确显示了正在发生的事情。

#10


1  

!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.

! !可能是紧凑的,但我认为这是不必要的复杂。在我看来,最好是禁用警告或使用三元操作符。

#11


0  

I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.

我要用b = (0 != t)——至少任何一个理智的人都能很容易地读懂。如果在代码中看到双党,我会非常惊讶。

#12


0  

Disable the warning.

禁用警告。

Write for clarity first; then profile; then optimize for speed, where required.

写清楚;然后概要;然后在需要的地方优化速度。

#13


0  

!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:

! !只有在使用算术方式的布尔表达式时才有用,例如:

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

(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing

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

bool b = !!extra;

makes as much sense as:

就像:

if (!!extra) { ... }

#14


-1  

The double not feels funny to me and in debug code will be very different than in optimized code.

在我和调试代码中,双重的感觉不是很有趣,它与优化后的代码非常不同。

If you're in love with !! you could always Macro it.

如果你爱上了!!你可以把它放大。

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

(as an aside, the ternary operator is what I favor in these cases)

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

#15


-1  

I recommend to use

我推荐使用

if (x != 0)

如果(x ! = 0)

or

if (x != NULL)

如果(x ! = NULL)

instead of if(x); it's more understandable and readable.

而如果(x);它更易于理解和可读性。

#16


-4  

I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.

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