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

少なくともブースト 1.50 ではvariables_map::clear()、変数マップを 経由で適切に補充できるようになりますstore。少なくともブースト 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;
}

次の出力が生成されます。

名前 = テスト
name = 別のテスト
于 2012-07-12T13:40:22.000 に答える