проверить повышение :: вариант <T>для нуля - PullRequest
17 голосов
/ 15 марта 2011

У меня в моей программе boost :: variable, и я хочу проверить, инициализирован ли сам вариант, а также есть ли значение, содержащееся в одном из его типов.

Я пробовал пустой () на вариант, но это не похоже на работу.Также не выполняется проверка на NULL.

Кто-нибудь знает, как это проверить?

РЕДАКТИРОВАТЬ: ОК, кажется, он никогда не будет пустым, но в его содержании не всегда будет значениетипы, так как я могу проверить ситуацию без значения?

Ответы [ 5 ]

35 голосов
/ 06 октября 2011

, если вы видите мой вопрос, касающийся никогда не пустой гарантии и единого хранилища , boost::variant поддерживает NIL-подобный тип значения с именем boost::blank что гарантирует, что вариант никогда не использует кучу в качестве хранилища резервных копий

Вы можете определить, какой тип хранится, используя boost::variant<>::which(), который возвращает целочисленный индекс типа варианта с привязкой; так что если вы используете пустой как первый тип, который () вернет 0, когда его пустое

см. Следующий пример

 typedef boost::variant< boost::blank , int , std::string > var_t;
 var_t a;
 assert( a.which() == 0 );
 a = 18;
 assert( a.which() == 1 );

надеюсь, это поможет

17 голосов
/ 15 марта 2011

A boost::variant всегда инициализируется.

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

struct Foo {};
struct Bar {};

struct Visitor: boost::static_visitor<>
{
  void operator()(Foo const& foo) const { std::cout << "Foo\n"; }
  void operator()(Bar const& bar) const { std::cout << "Bar\n"; }
};

int main(int argc, char* argv[])
{
  boost::variant<Foo,Bar> var;
  boost::apply_visitor(Visitor(), var); // prints Foo
  return 0;
}
4 голосов
/ 15 марта 2011

Один из способов убедиться, что у вас есть четко определенный вариант, - включить «NullType» в список вариантов.Несмотря на то, что может потребоваться написать больше кода в «посетителях», которые вы напишете для его использования, они могут выдавать исключения, чтобы операторы знали, что что-то не так.Я вообще против таких проверок во время выполнения, но иногда другого пути нет.Достаточно сказать, что:

class NullType{};

Затем добавьте его в качестве самого первого аргумента в список вариантов.Как уже говорили другие, и документация поддержки описывает, что у вас никогда не будет ситуации, когда вариант пуст.Однако вы можете выполнить проверку типа, чтобы убедиться, что вы никогда не сможете скомпилировать с «NullType», если вы не перегружаете функции или у вас возникает исключение времени выполнения, если у вас есть «NullType».1005 * Теперь ваш вариант:

boost::variant<NullType, int, double, long double> number;

class DoSomething : boost:static_visitor<void>{
public:
    void visit(const int& _item);
    void visit(const double& _item);
    void visit(const long double& _item);
    void visit(const NullType& _uhOh);
};
3 голосов
/ 15 марта 2011

Boost.Variant имеет гарантию никогда не пустой , что означает, что он всегда должен хранить некоторое значение.Это empty член гарантированно всегда возвращает false и существует только для совместимости.

Вы можете вместо этого Boost.Any .*

0 голосов
/ 29 мая 2016

Вы также можете использовать boost::variant<boost::blank, int, double, long double> number;

И вариант функции empty(). Возвращает false, если вариант всегда содержит ровно один из своих ограниченных типов. (Дополнительную информацию см. В разделе Гарантия "никогда не очищать" .)

...