Handle complex options with Boost's program_options

前端 未结 1 1071
醉梦人生
醉梦人生 2020-12-10 02:52

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

相关标签:
1条回答
  • 2020-12-10 03:28

    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 << "\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;
    }
    

    The validate function probably needs more rigor, but you get the idea.

    This compiles and works for me.

    0 讨论(0)
提交回复
热议问题