【问题标题】:parse custom objects through config file/command line using boost program options使用 boost 程序选项通过配置文件/命令行解析自定义对象
【发布时间】:2012-09-26 22:20:15
【问题描述】:

所以我刚刚开始为我的代码添加选项支持。我可以自己做,也可以使用 boost 的程序选项。唯一阻止我使用 boost 的是我添加到项目中的另一个依赖项。但是,如果它可以轻松处理复杂对象的解析,我更愿意付出代价。

我只是根据示例尝试了类似的方法,但它不起作用:

#include <boost/program_options.hpp>
namespace po = boost::program_options;


#include <iostream>
#include <fstream>
#include <iterator>
using namespace std;


struct Grid{
    double xmin, xmax;
};

int main(int ac, char* av[])
{
    try {
        Grid g;

        po::options_description cmd("Allowed options");
        cmd.add_options()
            ("help", "produce help message")
            ("Grid", "grid information")
            ;

        po::variables_map vm;
        store(parse_command_line(ac, av, cmd), vm);
        notify(vm);

        if (vm.count("help")) {
            cout << cmd << "\n";
            return 0;
        }

        g = vm["Grid"].as<Grid>();
        cout << g.xmin << " " << g.xmax << endl;

    }
    catch(exception& e)
    {
        cout << e.what() << "\n";
        return 1;
    }    
return 0;

当我使用./a.out --Grid {-1, 1} 运行代码时,我得到boost::bad_any_cast: failed conversion using boost::any_cast。我不明白这意味着什么,但我的猜测是我无法正确判断我的对象类型 Grid 的提升。如何使用 boost 正确执行此操作?

【问题讨论】:

    标签: c++ boost boost-program-options


    【解决方案1】:

    首先,简单的方法是使用po::value&lt;std::vector&lt;double&gt;&gt;()-&gt;multitoken(),: 但是,您需要传递这样的参数:--Grid -1 1

    int main(int ac, char* av[])
    {
        try {
    
            po::options_description cmd("Allowed options");
            cmd.add_options()
                ("help", "produce help message")
                ("Grid", po::value<std::vector<double>>()->multitoken(),
                 "grid information")
                ;
            po::variables_map vm;
            store(parse_command_line(ac, av, cmd), vm);
            notify(vm);
    
            if (vm.count("help")) {
                cout << cmd << "\n";
                return 0;
            }
    
            Grid g{vm["Grid"].as<std::vector<double>>()[0],
                   vm["Grid"].as<std::vector<double>>()[1]};
            cout << g.xmin << " " << g.xmax << endl;
    
        }
        catch(exception& e)
        {
            cout << e.what() << "\n";
            return 1;
        }
    }
    

    如果您想传递--Grid {-1,1} 之类的参数,可以添加operator&gt;&gt; 并自己解析std::string

    std::istream& operator>>(std::istream &in, Grid &g)
    {
        // Note that this code does not do any error checking, etc.
        // It is made simple on purpose to use as an example
        // A real program would be much more robust than this
        std::string line;
        std::getline(in, line);
        std::stringstream ss(line);
        char bracket, comma;
        double xmin, xmax;
        ss >> bracket >> xmin >> comma >> xmax;
        g = Grid{xmin, xmax};
        return in;
    }
    
    //...
    Grid g;
    try {
    
    //...
    cmd.add_options()
       ("help", "produce help message")
       ("Grid", po::value(&g), "grid information")
    ;
    //...
    
    cout << g.xmin << " " << g.xmax << endl;
    

    另外,请注意--Grid {-1,1}没有空格-1,1,而不是-1, 1。这是因为line 只会包含{-1,

    如果你想要空间,这里有一个可以解析--Grid {-1, 1}的例子,使用custom validatormultitoken

    // Showing only changes, rest of the code is the same
    void validate(boost::any& v, const std::vector<std::string>& val,
                  Grid*, double)
    {
        std::stringstream ss(val[0]);
        char bracket;
        double xmin, xmax;
        ss >> bracket >> xmin;
        ss.str(val[1]);
        ss >> xmax;
        v = Grid{xmin, xmax};
    }
    
    po::options_description cmd("Allowed options");
            cmd.add_options()
            ("help", "produce help message")
            ("Grid", po::value(&g)->multitoken(), "grid information")
            ;
    

    【讨论】:

      猜你喜欢
      • 2013-07-05
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多