Каков предпочтительный способ преобразования встроенного типа (int) в C ++ в C ++? - PullRequest
4 голосов
/ 31 января 2011

При программировании на Visual C ++, я думаю, каждый разработчик время от времени видит предупреждение

warning C4800: 'BOOL' : forcing value to bool 'true' or 'false'

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

Так что мой вопрос сейчас, учитывая любой встроенный числовой тип(int, short, ...), который должен интерпретироваться как логическое значение, каков / ваш предпочтительный способ фактического сохранения этого значения в переменную типа bool?

Примечание: Хотя смешивание BOOL и bool, вероятно, является плохой идеей, я думаю, что проблема неизбежно возникнет как в Windows, так и в другом месте, поэтому я думаю, что этот вопрос не относится ни к Visual-C ++, ни к Windows.

Учитывая int nBoolean; Я предпочитаю этот стиль:

  • bool b = nBoolean?true:false;

Возможны следующие варианты:

  • bool b = !!nBoolean;

  • bool b = (nBoolean != 0);

Есть ли вообще предпочтительный способ?Обоснование?

Я должен добавить: поскольку я работаю только с Visual-C ++, я не могу точно сказать, является ли это вопросом, специфичным для VC ++, или же такая же проблема возникает с другими компиляторами.Поэтому было бы интересно услышать от g ++ или пользователей, как они обрабатывают случай int-> bool.

Относительно стандарта C ++: как отмечает Дэвид Торнли в комментарии, стандарт C ++ не требует такого поведения.На самом деле, кажется, это явно разрешено, поэтому можно считать это странностью VC ++.Процитируем черновик N3029 (который есть у меня в атм.):

4.12 Булевы преобразования [conv.bool]

Значение арифметики, перечисление с незаданной областью, указатель илиуказатель на тип члена может быть преобразован в значение типа bool.Нулевое значение, нулевое значение указателя или нулевое значение указателя члена преобразуется в ложь;любое другое значение преобразуется в true.(...)

Ответы [ 7 ]

8 голосов
/ 31 января 2011

В контексте использования win32 SDK и MFC я обычно пишу так всегда. Это явно.

bool b = (myBOOL != FALSE);

РЕДАКТИРОВАТЬ: я редактировал :-), потому что я не уверен, что myBOOL == TRUE работает для всех реализаций BOOL и я могу предположить, что FALSE может иметь значение 0 большую часть времени.

4 голосов
/ 31 января 2011

Правильный способ, которым я предположил бы, является:

bool b = static_cast<bool>(val);
2 голосов
/ 31 января 2011

Три хороших способа:

static_cast<bool>( whatever )
bool( whatever )
!!whatever

Лично я предпочитаю последнее, но * nix люди могут реагировать отрицательно (не нужно для тех компиляторов, поэтому не знакомы с этой идиомой).

Одна из причин, по которой последняя из них хороша, заключается в том, что она закрывает Visual C ++ (принудительное подавление).

Неудачные способы включают сравнение с true или false, особенно с первым.

Cheers& hth.,

2 голосов
/ 31 января 2011

Я отдал свой голос за

BOOL nBoolean;
bool b = (nBoolean != 0);

Причина? Поскольку BOOL преобразуется в int, при преобразовании в bool его следует сравнивать с int. Два других метода: !!nBoolean и nBoolean?true:false обрабатывают nBoolean как логическое значение и поэтому выполняют неявное преобразование cast .

1 голос
/ 09 февраля 2011

Существует нет предпочтительного способа в C ++ , поскольку C ++ Std просто позволяет интегральное преобразование из int в bool. (Таким образом, предпочтительный путь по стандартному стандарту будет bool b = i;.)

Тем не менее, судя по другим ответам, в Visual C ++ (MS) даже не существует приемлемого способа сделать это, хотя на странице MSDN указано

... Если вы не можете переписать выражение использовать тип bool, тогда вы можете добавить «! = 0» к выражению, которое дает тип выражения bool. ...

Таким образом, один может заключить, что MS рекомендует использовать сравнение !=0, хотя я лично считаю, что это худшее из всех подавляющих предупреждение альтерративов, представленных в вопросе и ответах здесь: «type» в исходном коде - BOOL, и хотя на самом деле это просто int, по крайней мере следует сравнить «BOOL» с !=FALSE, как было предложено в некоторых других ответах.

1 голос
/ 31 января 2011

Я склонен писать так всегда..

bool b = !!myBOOL;

Это понятнее (как и говорящий по-английски, я привык к двойным негативам ....)

Это также безопаснее и позволяет избежать таких ошибок, как:

bool b = (myBOOL = FALSE); //oops!

Кроме того, я считаю, что логические значения никогда не следует сравнивать, используя == или !=, а && следует использовать.Как только == или != используется, логическая переменная больше не рассматривается как логическое значение, а как целое значение, которое побеждает цель логического значения.

0 голосов
/ 31 января 2011

Если бы это меня беспокоило, я бы написал вспомогательную функцию вроде

inline bool to_bool(BOOL b) {...}

, который скрыл бы одну из предложенных реализаций внутри него. И никогда больше об этом не думай :)

...