我有一个程序,使用不同的多级模型生成图形。 每个多级模型由一代较小的种子图(例如,50个节点)组成,可以从多个模型创建(例如 - 对于每个可能的边,选择以概率p包括它)。

在种子图生成之后,使用另一组模型之一将图扩展为更大的图(例如1000个节点)。

在两个阶段的每个阶段中,每个模型需要不同数量的参数。

我想让program_options根据模型的名称解析不同的可能参数。

例如,假设我有两个种子图模型:SA,有1个参数,SB,有两个。 同样对于扩展部分,我有两个模型:A和B,分别有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

并正确解析参数。 这甚至可能吗?

#1楼 票数:23 已采纳

通过使用自定义验证器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功能可能需要更严格,但你明白了。

这编译并为我工作。

  ask by R S translate from so

未解决问题?本站智能推荐:

3回复

如何使用 boost::program_options 创建选项别名?

我希望能够使用boost::program_options创建选项别名,将它们的参数存储在相同的键/标签下。 我的软件架构使用不同的专用选项解析器,具体取决于argv[1]值。 然而,有些选项是共享的,比如我的选项--inputs 。 为了与旧版本的程序兼容,我想在其中一个子解析器中添加一个兼
1回复

boost :: program_options是否可以使用这种可重复的选项?

我有选项--foo (缩写为-f )和--bar需要特殊处理,它们是可重复的,顺序应该很重要。 因此,对于以下情况: 我想设置一个可以构造[("foo", 1), ("foo", 2), ("bar", 3), ("foo", 4)]的键值映射。 请注意该元组数组的顺序,与命令行
2回复

boost::program_options 位置选项

我有一个位置选项(文件名),我希望它是最后一个选项。 用户可以在命令行上传入一堆东西,也可以使用-F作为文件名。 但是,我希望用户也能够将文件名放在最后。 例如: 我目前实现的代码允许调用者将文件名放在命令行中的任何位置。 有没有办法强制位置参数总是在“常规”参数之后? 这是我设置位置参数的
1回复

如何为boost :: program_options的位置选项添加描述?

我想使用不允许命名程序选项(如--files )的boost_program_options创建一个位置列表程序选项。 我有以下代码片段: 问题是我可以读取文件列表作为位置参数列表,如下所示: 但不幸的是也喜欢这个(我想禁用) 问题还在于产生的帮助: 所以我
1回复

boost :: program_options附加具有相似名称的矢量选项

我正在使用program_options来解析命令行和配置选项,但发现似乎是一个错误。 使用具有相似名称的矢量选项时,会出现问题。 如果我有一个未指定的参数“ myParam”和另一个指定的参数“ myParam2”,则库会将myParam的值附加到myParam2上。 例如,当我这样
4回复

boost :: program_options:迭代并打印所有选项

我最近开始使用boost::program_options ,发现它非常方便。 也就是说,有一件事遗漏,我无法以一种好的方式编码自己: 我想迭代在boost::program_options::variables_map收集的所有选项,以便在屏幕上输出它们。 这应该成为一个便利功能,我
1回复

仅在boost :: program_options中的短选项

如果没有他们的长期对手,我们将如何指定短期期权? 生成这个 有没有办法只指定短期权?
1回复

我可以使用Boost :: program_options一起解析可猜测和不可猜测的选项吗?

我有一些选择是相当冗长像-length -strength ,我想,让猜对他们来说,这样用户可以减少他们的名字。 另一方面,某些选项的短名称相互包含,例如-K1 -K10 ,对于那些当然应该禁用猜测。 我也有一个位置选项,我想保留所有对选项的标准检查:例如,我不想允许未知(错误输入)