4

再会,

我编写了一个类来通过 boost::program_options 解析配置文件。这是我所拥有的(缩短):

namespace nsProOp = boost::program_options;
nsProOp::variables_map m_variableMap;
nsProOp::options_description m_description;



// To add options to the variableMap, e.g. "addOption<int>("money_amount");"
template <class T>
    void addOption(const std::string& option, const std::string& helpDescription = "") {
        m_description.add_options()(option.c_str(), nsProOp::value<T > (), helpDescription.c_str());
    }



// And this is how i actually read the file:
void ConfigFile::parse() {
    std::ifstream file;
    file.open(m_pathToFile.c_str());

    nsProOp::store(nsProOp::parse_config_file(file, m_description, true), m_variableMap);
    nsProOp::notify(m_variableMap);      
}

好的,这很好用。但我希望能够再次解析同一个文件,以便我始终使用用户提供的最新条目!升压文档说关于“商店”:

“将在 'options' 中定义的所有选项存储在 'm' 中。如果 'm' 已经具有选项的非默认值,则该值不会更改,即使 'options' 指定了某个值。”

所以,如果我再次调用“parse()”,什么都不会发生,因为 m_variableMap 已被填充。我尝试调用 m_variableMap.clear() 并不能解决我的问题,因此 store 只能在第一次工作。

有人给我建议吗?如果我的问题不清楚,请告诉我。谢谢!

4

1 回答 1

11

至少在 boost 1.50 中,variables_map::clear()将允许通过store. 至少可以追溯到 boost 1.37 的另一种解决方案是在调用之前将默认构造的变量映射分配给变量映射store

void ConfigFile::parse() {
  std::ifstream file;
  file.open(m_pathToFile.c_str());
  m_variableMap = nsProOp::variables_map(); // Clear m_variableMap.
  nsProOp::store(nsProOp::parse_config_file(file, m_description, true), 
                 m_variableMap);
  nsProOp::notify(m_variableMap);      
}

这是一个示例程序:

#include <boost/program_options.hpp>
#include <iostream>
#include <fstream>
#include <string>

namespace po = boost::program_options;

void write_settings(const char* value)
{
  std::ofstream settings_file("settings.ini");
  settings_file << "name = " << value;
}

void read_settings(po::options_description& desc,
                   po::variables_map& vm)
{
  std::ifstream settings_file("settings.ini");

  // Clear the map.
  vm = po::variables_map();

  po::store(po::parse_config_file(settings_file , desc), vm);
  po::notify(vm);    
}

int main()
{
  std::string name;

  // Setup options.
  po::options_description desc("Options");
  desc.add_options()
    ("name", po::value<std::string>(&name), "name");
  po::variables_map vm;

  // Write, read, and print settings.
  write_settings("test");
  read_settings(desc, vm);
  std::cout << "name = " << name << std::endl;

  // Write, read, and print newer settings.
  write_settings("another test");
  read_settings(desc, vm);
  std::cout << "name = " << name << std::endl;
}

产生以下输出:

名称 = 测试
名称 = 另一个测试
于 2012-07-12T13:40:22.000 回答