Check boost:: variant <T> для null
У меня есть boost:: variant в моей программе, и я хочу проверить, инициализирован ли этот вариант, а также если есть значение, содержащееся в одном из его типов.
Я попробовал empty() для варианта, но это не работает. Также не проверяет NULL.
Кто-нибудь знает, как это проверить?
EDIT: Хорошо. Кажется, он никогда не будет пустым, но в нем не всегда будут значения, содержащиеся в типах, поэтому как я могу проверить ситуацию без значения?
Ответы
Ответ 1
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;
}
Ответ 2
если вы видите мой вопрос о неиспользуемой гарантии и отдельном хранилище, 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 );
надеюсь, что это поможет
Ответ 3
Один из способов убедиться, что у вас есть хорошо определенный вариант, - включить в список вариантов "NullType" . Хотя может потребоваться написать больше кода в "посетителях", которые вы напишете, чтобы использовать его, они могут создавать исключения, чтобы операторы знали, что что-то не так. Я вообще против таких проверок времени выполнения, но иногда нет другого пути. Достаточно сказать, что:
class NullType{};
Затем добавьте его как самый первый аргумент в список вариантов. Как говорили другие, и в документации по ускорению вы никогда не столкнетесь с ситуацией, когда вариант пуст. Тем не менее, вы можете сделать проверку типа, чтобы убедиться, что вы никогда не сможете скомпилировать с помощью "NullType" , если вы не перегружаете функции или не создаете исключение времени выполнения, если у вас есть "NullType" .
Теперь ваш вариант:
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);
};
Ответ 4
Boost.Variant имеет никогда непустую гарантию, а это значит, что он всегда должен хранить некоторое значение. Он empty
член всегда будет возвращать false
и существует только для совместимости.
Вместо этого вы можете проверить Boost.Any.
Ответ 5
Вы также можете использовать
boost::variant<boost::blank, int, double, long double> number;
И вариантная функция empty()
. Он возвращает false, если вариант всегда содержит ровно один из его ограниченных типов. (Дополнительную информацию см. В разделе Never-Empty Guarantee).