检查 boost::variant;对于空值

发布于 2024-10-23 13:50:40 字数 188 浏览 5 评论 0原文

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

我已经尝试过对该变体使用empty(),但这似乎不起作用。检查 NULL 也不行。

有谁知道如何检查这个吗?

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

I have a boost::variant in my program and I want to check if the variant itself is initialized and also if there is a value contained in one of it's types.

I've tried empty() on the variant, but that doesn't seem to work. Neither does checking against NULL.

Does anybody know how to check for this?

EDIT: Ok, It seems it will never be empty, but there will not always be a value in it's contained types, so how do I check for a no-value situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

迷你仙 2024-10-30 13:50:40

如果您看到我关于永不空保证和单一存储的问题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 );

希望这会有所帮助

if you see my question regarding never empty guarantee and single storage, boost::variant does support a NIL-like value type called boost::blank. which will guarantee that variant never uses the heap as backup storage

You can detect which type is stored using boost::variant<>::which() which returns an integer index of the binded variant type; so if you use blank as the first type, which() will return 0 when its blank

see the following example

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

hope this helps

甚是思念 2024-10-30 13:50:40

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;
}

A boost::variant is always initialized.

If you did not initalized it explicitly, the first item was constructed using its default constructor:

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;
}
送君千里 2024-10-30 13:50:40

确保您拥有明确定义的变体的一种方法是在变体列表中包含“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);
};

One method for making sure that you have a well defined variant is to include a "NullType" in your variant list. While it may neccessitate writing more code in the "visitors" you will write to use it, they can throw exceptions to let operators know something is amiss. I'm generally against such runtime checks but sometimes, there really isn't any other way. Suffice to say that:

class NullType{};

Then add it as the very first argument to the variant list. As others have said and the boost documentation describes you'll never have a situation where a variant is empty. However, you can do a type check to ensure that you won't ever be able to compile with "NullType" if you don't overload functions or have a runtime exception thrown if you do have a "NullType".

Now your variant:

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);
};
黑寡妇 2024-10-30 13:50:40

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

您可能需要查看 Boost.Any反而。

Boost.Variant has a never-empty guarantee, which means it must always store some value. It's empty member is guaranteed to always return false and exists only for compatibility.

You may want to check out Boost.Any instead.

耶耶耶 2024-10-30 13:50:40

您还可以使用
boost::variantnumber;

和变体函数 empty()。如果变量始终包含其有界类型之一,则返回 false。 (请参阅名为 的部分永不为空的保证了解更多信息。)

You also can use
boost::variant<boost::blank, int, double, long double> number;

And variant function empty(). It returns false if variant always contains exactly one of its bounded types. (See the section called Never-Empty Guarantee for more information.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文