Handle complex options with Boost#39;s program_options(使用 Boost 的 program_options 处理复杂的选项)
问题描述
我有一个程序可以使用不同的多级模型生成图形.每个多级模型都包含生成一个较小的种子图(例如 50 个节点),这些种子图可以从多个模型创建(例如 - 对于每个可能的边,选择以概率 p 包含它).
I have a program that generates graphs using different multi-level models. Each multi-level model consists of a generation of a smaller seed graph (say, 50 nodes) which can be created from several models (for example - for each possible edge, choose to include it with probability p).
在生成种子图后,使用另一组模型中的一个将图扩展为更大的图(比如 1000 个节点).
After the seed graph generation, the graph is expanded into a larger one (say 1000 nodes), using one of another set of models.
在两个阶段中的每一个阶段,每个模型都需要不同数量的参数.
In each of the two stages, each model require a different number of parameters.
我想让 program_options 根据模型的名称解析不同的可能参数.
I would like to be have program_options parse the different possible parameters, according to the names of the models.
例如,假设我有两个种子图模型:SA,有 1 个参数,SB,有两个.同样对于扩展部分,我有两个模型:A 和 B,同样分别具有 1 和 2 个参数.我希望能够执行以下操作:
For example, say I have two seed graphs models: SA, which has 1 parameters, and SB, which has two. Also for the expansion part, I have two models: A and B, again with 1 and 2 parameters, respectively. I would like to be able do something like:
./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
并正确解析参数.这可能吗?
and have the parameters parsed correctly. Is that even possible?
推荐答案
通过使用 自定义验证器 和 boost::program_options::value::multitoken,就可以达到想要的效果了:
By using a custom validator and boost::program_options::value::multitoken, you can achieve the desired result:
#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 << "
";
if (seedModel.param1)
std::cout << "Seed param1: " << *(seedModel.param1) << "
";
if (seedModel.param2)
std::cout << "Seed param2: " << *(seedModel.param2) << "
";
std::cout << "Expansion type: " << expansionModel.type << "
";
if (expansionModel.param1)
std::cout << "Expansion param1: " << *(expansionModel.param1) << "
";
if (expansionModel.param2)
std::cout << "Expansion param2: " << *(expansionModel.param2) << "
";
return 0;
}
validate
函数可能需要更严格,但你懂的.
The validate
function probably needs more rigor, but you get the idea.
这对我有用.
这篇关于使用 Boost 的 program_options 处理复杂的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Boost 的 program_options 处理复杂的选项
基础教程推荐
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01