Является!! безопасный способ конвертировать в bool в С++?

[Этот вопрос связан, но не совпадает с этим.]

Если я пытаюсь использовать значения определенных типов в виде булевых выражений, я получаю предупреждение. Вместо того, чтобы подавлять предупреждение, я иногда использую тернарный оператор (?:) для преобразования в bool. Использование двух не операторов (!!), похоже, делает то же самое.

Вот что я имею в виду:

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?

Итак, делает ли двойной метод не то же самое? Это более или менее безопасно, чем троичная техника? Является ли этот метод одинаково безопасным с нецелыми типами (например, с void * или double для T)?

Я не спрашиваю, хороший ли стиль !!t. Я спрашиваю, семантически ли это отличается от t ? true : false.

Ответы

Ответ 1

Аргумент! оператор и первый аргумент тернарного оператора оба неявно преобразуются в bool, так что!! и?: являются ИМО глупыми излишними украшениями актеров. Я голосую за

b = (t != 0);

Нет неявных преобразований.

Ответ 2

В качестве альтернативы вы можете сделать это: bool b = (t != 0)

Ответ 3

Осторожно!

  • Логическое значение имеет истина и ложность.
  • Целое число содержит целые числа.

Это очень разные понятия:

  • Истина и ложность - это решающий материал.
  • Цифры относятся к подсчету.

При согласовании этих концепций это должно быть сделано явно. Мне нравится версия Димы лучше всего:

b = (t != 0);

Этот код ясно говорит: Сравните два числа и сохраните значение истинности в логическом.

Ответ 4

Все действующие методы, все будут генерировать один и тот же код.

Лично я просто отключу предупреждение, поэтому могу использовать самый чистый синтаксис. Кастинг в bool - это не то, о чем я беспокоюсь о случайности.

Ответ 5


Да, это безопасно.


0 интерпретируется как ложное, все остальное верно, Отсюда, следовательно, 5 появляется как ложный 0! 0
так!! 5 выходит как истина

Ответ 6

Я бы не использовал:

bool b = !!t;

Это наименее читаемый способ (и, следовательно, самый сложный для поддержания)

Другие зависят от ситуации.
Если вы конвертируете только в выражение bool.

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.

Резюме: Используйте то, что дает наибольшее значение для контекста, в котором вы находитесь.
Попробуйте сделать это очевидным, что вы делаете.

Ответ 7

Я рекомендую никогда не подавлять это предупреждение и никогда не использовать c cast (bool) для его подавления. Конверсии могут не всегда вызываться, как вы предполагаете.

Существует различие между выражением, которое вычисляется как true и boolean этого значения.

Оба! и тройной подход к привыканию, но выполняет работу аналогичным образом, если вы не хотите определять внутренние типы с перегруженными приведениями в bool.

Подход Dima тоже хорош, так как он присваивает значение выражения bool.

Ответ 8

Если вы беспокоитесь об этом предупреждении, вы также можете заставить литье: bool b = (bool)t;

Ответ 9

Я действительно ненавижу!! t!!!!!!. Это приносит худшее в C и С++, соблазн быть слишком умным наполовину с вашим синтаксисом.

bool b (t!= 0);//Это лучший способ ИМХО, он явно показывает, что происходит.

Ответ 10

!! может быть компактным, но я думаю, что это излишне сложно. Лучше отключить предупреждение или использовать тернарный оператор, на мой взгляд.

Ответ 11

Я бы использовал b = (0!= t) - по крайней мере любой здравомыслящий человек может легко его прочитать. Если бы я увидел двойной код в коде, я был бы очень удивлен.

Ответ 12

Отключите предупреждение.

Сначала пишите для ясности; затем профиль; затем оптимизируйте скорость, где это необходимо.

Ответ 13

!! полезно, когда вы используете логическое выражение в арифметическом режиме, например:

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

(Чей стиль - это другое обсуждение.) Когда все, что вам нужно, это логическое выражение,!! является избыточным. Запись

bool b = !!extra;

имеет такой же смысл, как:

if (!!extra) { ... }

Ответ 14

Двойной не чувствует себя забавным для меня, а в коде отладки будет сильно отличаться от оптимизированного кода.

Если ты влюбился! вы всегда можете сделать макрос.

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

(как в стороне, тернарный оператор - это то, что я предпочитаю в этих случаях)

Ответ 15

Я рекомендую использовать

if (x!= 0)

или

if (x!= NULL)

вместо if (x); это более понятно и читаемо.

Ответ 16

Я бы использовал bool b = t и оставил предупреждение компиляции, комментируя эту конкретную безопасность линии. Отключение предупреждения может укусить вас в прикладе в другой части кода.