如何检索模板化 class 的 boost::variant 值

How to retrieve a boost::variant value for a templated class

我正在尝试使用 c++11 中的 boost::variant 来创建它,但我不确定如何创建。 所以我有这个模板化的结构 class data<>

typedef boost::variant< data<A>,data<B>> dataVar;

存储在

std::map<string,dataVar> dataMap

如果我能以某种方式检索数据的类型,这样我就可以分配值,那就太好了,但我不知道如何优雅地完成这项工作

void registerDataFor(string str)
  {
     auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

     dataVar = itr->second;
     data<v.which()> itemData= boost::get<v.which()>(v);
     someArray.push_back(itemData.getIntegerValue());
     registerDataFor(itemData.getString());
  }

这不会编译,因为模板括号需要静态类型。

我看过其他建议访客设计的回复,但我还需要数据类型 <> 才能获取项目。

假设 data<A>data<B> 具有相同的界面,您可以使用访问者 structtemplate operator():

struct registerImpl : boost::static_visitor<void>
{
    template <typename T>
    void operator()(T& x) const
    {
        someArray.push_back(x.getIntegerValue());
        registerDataFor(x.getString());   
    }
};

void registerDataFor(std::string str)
{
    auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

    registerImpl visitor;
    boost::apply_visitor(visitor, itr->second);
}

wandbox example


在 C++14 中,您可以使用 generic lambda.

就地 访问变体
void registerDataFor(std::string str)
{
    auto itr = dataMap.find(str);

    if(itr == dataMap.end())
        return;

    boost::apply_visitor([](auto& x){
        someArray.push_back(x.getIntegerValue());
        registerDataFor(x.getString());      
    }, itr->second);
}

wandbox example


(如果您对使用 lambda 和 C++14 功能进行变体访问感兴趣,我已经写了两篇关于它的文章:part 1 and part 2。)