Как лучше конвертировать VARIANT_BOOL в C ++ bool? - PullRequest
22 голосов
/ 20 мая 2009

При использовании COM логические значения передаются как VARIANT_BOOL, который объявлен в wtypes.h как short . Есть также предопределенные значения для true и false :

#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#define VARIANT_FALSE ((VARIANT_BOOL)0)

Каков наилучший способ преобразования из типа VARIANT_BOOL в тип C ++ bool? Очевидные варианты:

  1. сравнить с VARIANT_FALSE

  2. просто приведение к bool

Другие способы могут быть легко изобретены.

Каков наилучший способ сделать это - наиболее читабельный, наиболее совместимый со стандартами, наименее склонный к установке случайных ошибок и наименее подверженный проблемам с портированием на 64-битные платформы?

Ответы [ 6 ]

29 голосов
/ 20 мая 2009

Сравните с VARIANT_FALSE. Существует много глючного кода, который по ошибке передает значение C ++ bool true (приведенное к целочисленному значению 1) функции, ожидающей VARIANT_BOOL. Если вы сравните с VARIANT_FALSE, вы все равно получите правильное ожидаемое значение.

10 голосов
/ 21 мая 2009

Мне не нужно беспокоиться о совместимости между различными логическими значениями, поэтому я обычно пишу:

VARIANT_BOOL vb_bool = VARIANT_FALSE;

// ... vb_bool set to something by some other code

bool myBool = (vb_bool == VARIANT_TRUE);

Существуют ли более мелкие (как в "будет компилироваться в более простой код x86") действительные способы сделать это? Конечно. Не стоит того. Это гарантированно работает, поэтому я могу беспокоиться о своей бизнес-логике.

4 голосов
/ 20 мая 2009

Приведение к bool явно неверно. Некоторые люди говорят (например, комментарии на BOOL против VARIANT_BOOL против BOOLEAN против bool ), чтобы сравнить с VARIANT_FALSE, но я бы сравнил оба. Таким образом, вы ловите недопустимые значения (что угодно, кроме VARIANT_FALSE или VARIANT_TRUE) рано.

, например

bool VariantBoolToBool(VARIANT_BOOL varFlag)
{
  bool boolFlag;

  switch( varFlag ) 
  {
    case VARIANT_TRUE:
        boolFlag = true;
        break;
    case VARIANT_FALSE:
        boolFlag = false;
        break;
    default:
        throw Exception("Not a valid value");
  }

  return boolFlag;
}
1 голос
/ 20 мая 2009

Объявите этот макрос в одном из ваших глобальных заголовков.

#define b(X) ((X)!=VARIANT_FALSE)


РЕДАКТИРОВАТЬ: гораздо более безопасная версия:

inline bool b(VARIANT_BOOL v){return v!=VARIANT_FALSE;}
1 голос
/ 20 мая 2009

Почему есть явное приведение?

if (my_bool)
{
    blargh();
}
else
{
   blarglerr();
}

Таким образом, true - это true, а false - это false, согласно стандарту C. Если вам нужно установить стиль C ++ bool, сделайте что-то вроде:

VARIANT_BOOL vb_bool = VARIANT_FALSE
bool cpp_bool = !!vb_bool
0 голосов
/ 20 мая 2009

Стандартные правила преобразования C ++ полагаются на ноль, что означает ложь [и, как указывает 1800 ИНФОРМАЦИЯ, вариант ИСТИНА - это то, где происходит наибольшая путаница], и больше ничего. Следовательно, static_cast будет лучше.

Но во многих случаях код будет более читабельным для сравнения. В этом случае VARIANT_BOOL - это то, с чем нужно сравнивать.

...