c++ - 使用 Boost 的 program_options 处理复杂的选项

标签 c++ boost parameters graph boost-program-options

我有一个程序可以使用不同的多级模型生成图形。每个多级模型都包含一代较小的种子图(例如,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

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

最佳答案

通过使用 custom validatorboost::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 函数可能需要更严格,但你明白了。

这对我来说是编译和工作的。

关于c++ - 使用 Boost 的 program_options 处理复杂的选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2935587/

相关文章:

c++ - 光线追踪 - 折射错误

c++ - 宽阔的溪流和炭

c++ - 在boost中为动态数组定义自定义步进器

c++ - 使用 boost spirit 解析为结构

javascript - Angular:如何从单选按钮组获取数据并将其作为参数传递给方法?

c++:ifstream打开问题,为文本文件名传递字符串

c++ - OpenCV 2.4.13 错误 : ‘Moments’ in namespace ‘cv’ does not name a type

c++ - 帮助 boost::regex 修剪

scala - 在 Scala 的构造函数上重新分配一个 var 参数

c++ - 使用模板编译时计算使用 const 值初始化数组