Boost's Program_optionsで複雑なオプションを処理します
-
05-10-2019 - |
質問
さまざまなマルチレベルモデルを使用してグラフを生成するプログラムがあります。各マルチレベルモデルは、いくつかのモデル(たとえば、可能なエッジごとに、確率Pで含めることを選択する)から作成できる小さなシードグラフ(たとえば、50ノードなど)で構成されています。
シードグラフの生成の後、グラフは、モデルの別のセットの1つを使用して、より大きなもの(たとえば1000ノードなど)に拡張されます。
2つの段階のそれぞれで、各モデルには異なる数のパラメーターが必要です。
モデルの名前に従って、プログラム_optionsがさまざまな可能なパラメーターを解析したいと思います。
たとえば、たとえば、2つのシードグラフモデルがあるとします:SAには1つのパラメーターがあるSAと2つのSBがあります。また、拡張部分には、AとBの2つのモデルがあります。これも1つと2つのパラメーターを使用します。私は次のようなことをすることができたいです:
./graph_generator --seed=SA 0.1 --expansion=A 0.2
./graph_generator --seed=SB 0.1 3 --expansion=A 0.2
./graph_generator --seed=SA 0.1 --expansion=B 10 20
./graph_generator --seed=SB 0.1 3 --expansion=B 10 20
パラメーターを正しく解析します。それも可能ですか?
解決
aを使用して カスタムバリデーター と boost :: program_options :: value :: multitoken, 、あなたは望ましい結果を達成することができます:
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/program_options.hpp>
// Holds parameters for seed/expansion model
struct Model
{
std::string type;
boost::optional<float> param1;
boost::optional<float> param2;
};
// Called by program_options to parse a set of Model arguments
void validate(boost::any& v, const std::vector<std::string>& values,
Model*, int)
{
Model model;
// Extract tokens from values string vector and populate Model struct.
if (values.size() == 0)
{
throw boost::program_options::validation_error(
"Invalid model specification");
}
model.type = values.at(0); // Should validate for A/B
if (values.size() >= 2)
model.param1 = boost::lexical_cast<float>(values.at(1));
if (values.size() >= 3)
model.param2 = boost::lexical_cast<float>(values.at(2));
v = model;
}
int main(int argc, char* argv[])
{
Model seedModel, expansionModel;
namespace po = boost::program_options;
po::options_description options("Generic options");
options.add_options()
("seed",
po::value<Model>(&seedModel)->multitoken(),
"seed graph model")
("expansion",
po::value<Model>(&expansionModel)->multitoken(),
"expansion model")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, options), vm);
po::notify(vm);
std::cout << "Seed type: " << seedModel.type << "\n";
if (seedModel.param1)
std::cout << "Seed param1: " << *(seedModel.param1) << "\n";
if (seedModel.param2)
std::cout << "Seed param2: " << *(seedModel.param2) << "\n";
std::cout << "Expansion type: " << expansionModel.type << "\n";
if (expansionModel.param1)
std::cout << "Expansion param1: " << *(expansionModel.param1) << "\n";
if (expansionModel.param2)
std::cout << "Expansion param2: " << *(expansionModel.param2) << "\n";
return 0;
}
validate
機能にはおそらくもっと厳密なものが必要ですが、アイデアが得られます。
これは私のためにコンパイルして機能します。
所属していません StackOverflow