boost :: program_options如何重新加载值

sjc*_*omp 5 c++ boost boost-program-options

我想从配置文件中重新加载一些值。我知道,po::store如果值存在于中,则不会更改variables_map。是否有替代方法即使值已经存在也可以替换?

我尝试从中删除要重新加载的值variables_map,但是po::store无论如何都不会添加新值(即使也无法访问旧值)。

Dar*_*ioP 6

P3trus的解决方案涉及向下转换。这是必要的,因为variables_map重载std::map::operator[]返回a const variable_value &const防止重新分配)。

但是在C ++ 11中,我们std::map::at()没有重载它,因此可以这样做:

vm.at(option).value() = val;
Run Code Online (Sandbox Code Playgroud)

直接在需要的地方。


P3t*_*rus 5

问题在于变量映射会记住哪些选项是最终的。如果您查看源代码,则会找到以下条目。

/** Names of option with 'final' values -- which should not
    be changed by subsequence assignments. */
std::set<std::string> m_final;
Run Code Online (Sandbox Code Playgroud)

它是variables_map的私有成员变量。

我猜最简单的方法是使用新的variables_map并替换旧的。如果您需要一些旧值,或者只想替换其中一些,请编写自己的存储函数。您基本上可以使用po :: store创建一个临时的variables_map,然后根据需要更新他们的variables_map。

variables_map本质上是std :: map,因此您可以以相同的方式访问其内容。它存储一个po :: variable_value,类似于boost :: any对象的包装器。如果您只想替换一个值,则可以使用类似的东西

template<class T>
void replace(  std::map<std::string, po::variable_value>& vm, const std::string& opt, const T& val)
{
  vm[option].value() = boost::any(val);
}
Run Code Online (Sandbox Code Playgroud)

注意:po是名称空间别名。

namespace po = boost::program_options;
Run Code Online (Sandbox Code Playgroud)