通常从boost :: variant <t>转换为type </t>

时间:2010-12-06 11:09:28

标签: c++ unions

我有一个typedef boost::variant<int, float, double, long, bool, std::string, boost::posix_time::ptime> variant,用于在结构中存储不同类型的值。只有一种特定类型将存储在该结构中,但是我有一个这些结构的向量,我需要通过它来获取变体的实际类型。

现在当我需要进行转换时,我会这样做:

variant second = mystruct.variant;
                                if (second.which() == 5) //string 
                    {
                        std::string val = boost::get<std::string>(second);
                        modvalue->AddNodeAttribute(key, val);
                    }
                    else if (second.which() == 0) //int
                    {
                        int val = boost::get<int>(second);
                        modvalue->AddNodeAttribute(key, val);
                    }
                    else if (second.which() == 2) //double
                    {
                        double val = boost::get<double>(second);
                        modvalue->AddNodeAttribute(key,val);
                    }
                    else if (second.which() == 1) //float
                    {
                        float val = boost::get<float>(second);
                        modvalue->AddNodeAttribute(key, val);
                    }
                    else if (second.which() == 3) // long
                    {
                        long val = boost::get<long>(second);
                        modvalue->AddNodeAttribute(key, val);
                    }
                    else if (second.which() == 4) // bool
                    {
                        bool val = boost::get<bool>(second);
                        modvalue->AddNodeAttribute(key, val);
                    }
                    else if (second.which() == 6) // posix::time
                    {
                        boost::posix_time::ptime ptm = boost::get<boost::posix_time::ptime>(second);
                        modvalue->AddNodeAttribute(key, ptm);
                    }

我想知道是否有更通用的方法我可以通过编写一个采用变量的通用函数和一个返回值类型T来解决这个问题。但是当我这样做时,我仍然需要编写类似的if语句来解释每种类型的T。

类似于FromVariant<int>(var);,但我仍然需要为我的变体中的每个类型执行此操作。

所以看起来我的通用解决方案并没有减少我的代码,而是增加了代码,这显然不是重点。我想知道是否有人有一个更优雅的解决方案来获取我的变体中的各种类型,这有点通用,我可以调用一个函数给出我想要的类型?

3 个答案:

答案 0 :(得分:11)

实际上看一下你的代码,这里有一个不同的选择 - 再次基于使用访问者..

struct add_node_visitor : boost::static_visitor<>
{
  add_node_visitor(<type of modvalue> & node, <type of key> & key) : _node(node), _key(key) {}

  template <typename _Item>
  void operator()(_Item const& item)
  {
    node->AddNodeAttribute(_key, item);
  }  

  <type of modvalue> & _node;
  <type of key> & _key;
}

使用:

boost::apply_visitor (add_node_visitor(modmodvalue, key), mystruct.variant);

只要您的AddNodeAttribute对所有类型都有重载,上面的内容应该有效......

答案 1 :(得分:2)

当我使用boost::variant时,我总是使用访问者技术访问包含的数据。在我看来,这是一种非常优雅的方式。它不依赖于开关逻辑,这实际上是糟糕设计的标志。请参阅documentation

祝你好运!

答案 2 :(得分:0)

... AddNodeAttribute做什么?每种类型基本上都是一样的,对吧?如果某个地方有一个节点属性容器,那么它基本上需要是变体类型的容器,对吗?

...那么为什么不将AddNodeAttribute重写为接受变体的单个函数呢?