初始化std :: variant的映射以表示JSON文件

时间:2018-02-07 11:24:31

标签: c++ variant c++17

作为学校项目的一部分,我必须阅读JSON配置文件以填充自定义Conf对象,该对象定义如下:

struct ConfValue;
using ConfObject = std::map<std::string, ConfValue>;
using ConfArray = std::vector<ConfValue>;

/**
* Represents a configuration value.
*/
struct ConfValue {
    std::variant<std::monostate, ConfObject, ConfArray, std::string, long long, double, bool> v;
};

/**
* Configuration (format influenced by JSON).
*/
using Conf = ConfObject;

我希望能够构造一个由此JSON文件表示的默认对象:

{
      "port": 4242,
      "module": "modheader",
      "modulePath": ["../modules/", "./modules"]
}

这可以为我提供搜索真实配置文件的地图,每个字段的类型以及每个字段的默认值。

我尝试使用支撑初始化来做到这一点,但无论我尝试什么,都不会编译:

  Conf default_conf_{
    {"port", ConfValue{4242}},
    {"module", ConfValue{"modHeader"}},
    {"modulePath", ConfArray{"../modules/", "./modules"}}
  };

我正在尝试用c ++做什么,如果是,怎么做? :)

附带问题:是否可以在运行时获取std :: variant的类型?

2 个答案:

答案 0 :(得分:2)

您可以使用:

Conf default_conf {
    {"port", ConfValue{4242LL}},
    {"module", ConfValue{"modHeader"}},
    {"modulePath", ConfValue{ConfArray{ConfValue{"../modules/"}, ConfValue{"./modules"}}}}
};

Demo

答案 1 :(得分:1)

这里有两个独立的问题。

首先,如果没有更多帮助,4242将无法运作。您可以将其减少为:

std::variant<long long, bool> v = 4242; // error

转换含糊不清。所以你必须做出没有或其他更好的匹配。因此,4242LL

其次,您只需要modulePath值中的更多大括号 - 因为我们需要列出 - 初始化所有ConfValue,我们不能只构建它们:

Conf default_conf_{{
  {"port", {4242LL}},
  {"module", {"modHeader"}},
  {"modulePath", {ConfArray{{"../modules/"}, {"./modules"}}}}
}};   

你需要ConfArray基本上只是确定所有这些括号的含义。如果您向ConfValue添加了一些构造函数,那么您也可以省略它。