18

我的程序中有一个 boost::variant ,我想检查变体本身是否已初始化,以及其中一种类型中是否包含值。

我已经在变体上尝试了 empty() ,但这似乎不起作用。也不会检查 NULL。

有人知道如何检查吗?

编辑:好的,它似乎永远不会为空,但它所包含的类型中并不总是有一个值,那么如何检查无值情况?

4

5 回答 5

39

如果您看到我关于永不为空的保证和单一存储的问题boost::variant它确实支持类似于 NIL 的值类型,称为boost::blank. 这将保证变体永远不会使用堆作为备份存储

boost::variant<>::which()您可以使用返回绑定变体类型的整数索引来检测存储的类型;因此,如果您使用空白作为第一种类型,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 );

希望这可以帮助

于 2011-10-05T22:32:16.850 回答
18

Aboost::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;
}
于 2011-03-15T13:32:16.863 回答
4

确保您有明确定义的变体的一种方法是在您的变体列表中包含“NullType”。虽然可能需要在“访问者”中编写更多代码才能使用它,但它们可能会抛出异常以让操作员知道有问题。我通常反对这种运行时检查,但有时,真的没有其他办法。可以这么说:

class NullType{};

然后将它作为第一个参数添加到变体列表中。正如其他人所说,boost 文档描述了你永远不会遇到变体为空的情况。但是,您可以进行类型检查以确保如果您不重载函数或如果您确实有“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);
};
于 2011-03-15T14:07:22.170 回答
3

Boost.Variant 有一个永不为空的保证,这意味着它必须始终存储一些值。它的empty成员保证总是返回false并且只为了兼容性而存在。

您可能想改为查看Boost.Any

于 2011-03-15T13:32:48.410 回答
0

你也可以使用 boost::variant<boost::blank, int, double, long double> number;

和变体功能empty()。如果变体始终包含其有界类型之一,则返回 false。(有关更多信息,请参阅“永不空包保证”部分。)

于 2016-05-29T16:13:02.127 回答