Ответ 1
Аргумент! оператор и первый аргумент тернарного оператора оба неявно преобразуются в bool, так что!! и?: являются ИМО глупыми излишними украшениями актеров. Я голосую за
b = (t != 0);
Нет неявных преобразований.
[Этот вопрос связан, но не совпадает с этим.]
Если я пытаюсь использовать значения определенных типов в виде булевых выражений, я получаю предупреждение. Вместо того, чтобы подавлять предупреждение, я иногда использую тернарный оператор (?:
) для преобразования в 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
.
Аргумент! оператор и первый аргумент тернарного оператора оба неявно преобразуются в bool, так что!! и?: являются ИМО глупыми излишними украшениями актеров. Я голосую за
b = (t != 0);
Нет неявных преобразований.
В качестве альтернативы вы можете сделать это: bool b = (t != 0)
Осторожно!
Это очень разные понятия:
При согласовании этих концепций это должно быть сделано явно. Мне нравится версия Димы лучше всего:
b = (t != 0);
Этот код ясно говорит: Сравните два числа и сохраните значение истинности в логическом.
Все действующие методы, все будут генерировать один и тот же код.
Лично я просто отключу предупреждение, поэтому могу использовать самый чистый синтаксис. Кастинг в bool - это не то, о чем я беспокоюсь о случайности.
Да, это безопасно.
0 интерпретируется как ложное, все остальное верно,
Отсюда, следовательно, 5 появляется как ложный
0! 0
так!! 5 выходит как истина
Я бы не использовал:
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.
Резюме:
Используйте то, что дает наибольшее значение для контекста, в котором вы находитесь.
Попробуйте сделать это очевидным, что вы делаете.
Я рекомендую никогда не подавлять это предупреждение и никогда не использовать c cast (bool) для его подавления. Конверсии могут не всегда вызываться, как вы предполагаете.
Существует различие между выражением, которое вычисляется как true и boolean этого значения.
Оба! и тройной подход к привыканию, но выполняет работу аналогичным образом, если вы не хотите определять внутренние типы с перегруженными приведениями в bool.
Подход Dima тоже хорош, так как он присваивает значение выражения bool.
Если вы беспокоитесь об этом предупреждении, вы также можете заставить литье: bool b = (bool)t;
Я действительно ненавижу!! t!!!!!!. Это приносит худшее в C и С++, соблазн быть слишком умным наполовину с вашим синтаксисом.
bool b (t!= 0);//Это лучший способ ИМХО, он явно показывает, что происходит.
!! может быть компактным, но я думаю, что это излишне сложно. Лучше отключить предупреждение или использовать тернарный оператор, на мой взгляд.
Я бы использовал b = (0!= t) - по крайней мере любой здравомыслящий человек может легко его прочитать. Если бы я увидел двойной код в коде, я был бы очень удивлен.
Отключите предупреждение.
Сначала пишите для ясности; затем профиль; затем оптимизируйте скорость, где это необходимо.
!! полезно, когда вы используете логическое выражение в арифметическом режиме, например:
c = 3 + !!extra; //3 or 4
(Чей стиль - это другое обсуждение.) Когда все, что вам нужно, это логическое выражение,!! является избыточным. Запись
bool b = !!extra;
имеет такой же смысл, как:
if (!!extra) { ... }
Двойной не чувствует себя забавным для меня, а в коде отладки будет сильно отличаться от оптимизированного кода.
Если ты влюбился! вы всегда можете сделать макрос.
#define LONGTOBOOL(x) (!!(x))
(как в стороне, тернарный оператор - это то, что я предпочитаю в этих случаях)
Я рекомендую использовать
if (x!= 0)
или
if (x!= NULL)
вместо if (x); это более понятно и читаемо.
Я бы использовал bool b = t и оставил предупреждение компиляции, комментируя эту конкретную безопасность линии. Отключение предупреждения может укусить вас в прикладе в другой части кода.