是否可以使用包含boost :: variant的STL容器并在变体类型本身中使用相同的容器类型?

Max*_*Max 5 c++ boost stl

这似乎不太可能,但我想我还是会问.

我已经定义了boost::variant这样的:

typedef boost::variant<double, int, std::string> ConfigVariant;
Run Code Online (Sandbox Code Playgroud)

稍后在我的代码中我定义了std::map这样的:

std::map<std::string, ConfigVariant> my_map;
Run Code Online (Sandbox Code Playgroud)

现在我希望能够拥有std::map<std::string, ConfigVariant>内在的价值观my_map.例如,我想这样做:

my_map[key1][key2] = "hello world";
Run Code Online (Sandbox Code Playgroud)

我认为这是不可能的原因是因为看起来相应的变体定义看起来像这样:

typedef boost::variant<double, int, std::string, std::map<std::string, ConfigVariant> ConfigVariant;
Run Code Online (Sandbox Code Playgroud)

由于制作这样的类型定义是不可能的,有什么方法可以解决这个问题吗?

llo*_*miz 7

官方文档有一个关于递归变体类型的部分.它解释了两种方法:使用boost::recursive_wrapperboost::make_recursive_variant.我不确定是否有可能定义这种递归recursive_wrapper(我从来没有亲自,但我远非专家).与之相反,make_recursive_variant它非常简单:您只需要替换递归变体类型,boost::recursive_variant_然后使用它::type来评估元函数并获得所需的类型.

typedef boost::make_recursive_variant<
                    double,
                    int, 
                    std::string,
                    //std::map<std::string,ConfigVariant>
                    std::map<std::string,boost::recursive_variant_>
        >::type ConfigVariant;
Run Code Online (Sandbox Code Playgroud)

在coliru上运行

#include <iostream>
#include <string>
#include <map>

#include <boost/variant.hpp>

typedef boost::make_recursive_variant<double, int, std::string, std::map<std::string, boost::recursive_variant_> >::type ConfigVariant;

struct printer : boost::static_visitor<>
{
    void operator()(int val) const
    {
        std::cout << val;
    }
    void operator()(double val) const
    {
        std::cout << val;
    }
    void operator()(const std::string& val) const
    {
        std::cout << val;
    }
    void operator()(const std::map<std::string,ConfigVariant>& val) const
    {
        std::cout << "map_of{ ";
        for(std::map<std::string,ConfigVariant>::const_iterator it=val.begin(),end=val.end(); it!=end; ++it)
        {
            boost::apply_visitor(*this,it->second);
            std::cout << " ";
        }
        std::cout << "}";   
    }
};


int main()
{
    ConfigVariant intconf=1;
    ConfigVariant doubleconf=1.2;
    ConfigVariant stringconf="conf";
    std::map<std::string, ConfigVariant> mapconf, mapconf2;
    mapconf["int"]=intconf;
    mapconf["string"]=stringconf;
    mapconf2["map"]=mapconf;
    mapconf2["double2"]=doubleconf;
    ConfigVariant visitable=mapconf2;

    boost::apply_visitor(printer(), visitable);
    std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)