Как извлечь последовательность проанализированных параметров с помощью параметров программы Boost?

Я создаю генератор графов, используя Boost Graph и Program Options. Например, есть два типа компонентов C и W, каждый с 1 источником, 1 приемником и некоторыми дополнительными параметрами для указания промежуточной топологии. Я хотел бы иметь возможность сшивать их вместе в последовательности, заданной порядком аргументов командной строки.

Например:

./bin/make_graph -c4,5,1 -w3,3 -c3,1,2

Должен создаться график, похожий на следующий:

C -- W -- C

Но:

./bin/make_graph -c4,5,1 -c3,1,2 -w3,3

Должен создаться график, похожий на следующий:

C -- C -- W

Используя параметры программы boost ::_, я не смог определить, как извлечь точный порядок, поскольку он «составляет» параметры одного и того же строкового ключа _в карту со значением _type == vector< строка > (в моем случае ).

При переборе карты порядок теряется. Есть ли способ не дублировать синтаксический анализ, но иметь функцию с именем (, возможно, обратный вызов )каждый раз, когда анализируется параметр? Я не смог найти документацию в этом направлении. Любые другие предложения?

Чтобы убедить вас, что я не выдумываю, вот что у меня есть:

    namespace bpo = boost::program_options;
    std::vector<std::string> args_cat, args_grid, args_web;
    bpo::options_description desc("Program options:");
    desc.add_options()
           .operator ()("help,h","Displays this help message.")
           .operator ()("caterpillar,c",bpo::value< std::vector<std::string> >(&args_cat)->default_value( std::vector<std::string>(1,"4,7,2"), "4,7,2" ),"Caterpillar tree with 3 parameters")
           .operator ()("grid,g",bpo::value< std::vector<std::string> >(&args_grid)->default_value( std::vector<std::string>(1,"3,4"), "3,4" ),"Rectangular grid with 2 parameters")
           .operator ()("web,w",bpo::value< std::vector<std::string> >(&args_web)->default_value( std::vector<std::string>(1,"3,4"), "3,4" ),"Web with 2 parameters")
            ;
    bpo::variables_map ops;
    bpo::store(bpo::parse_command_line(argc,argv,desc),ops);
    bpo::notify(ops);
    if((argc < 2) || (ops.count("help"))) {
        std::cout << desc << std::endl;
        return;
    }
    //TODO: remove the following scope block after testing
    {
        typedef bpo::variables_map::iterator OptionsIterator;
        OptionsIterator it = ops.options.begin(), it_end = ops.options.end();
        while(it != it_end) {
            std::cout << it->first << ": ";
            BOOST_FOREACH(std::string value, it->second) {
                std::cout << value << " ";
            }
            std::cout << std::endl;
            ++it;
        }
        return;
    }

Я понимаю, что я мог бы также включить тип в качестве параметра и решить эту проблему тривиально, например.:

./bin/make_graph --component c,4,5,1 --component w,3,3 --component c,3,1,2

но это движется в направлении написания парсера/валидатора самостоятельно (, возможно, даже без использования опций программы Boost):

./bin/make_graph --custom c,4,5,1,w,3,3,c,3,1,2
./bin/make_graph c,4,5,1,w,3,3,c,3,1,2

Как бы вы, ребята, порекомендовали мне сделать это элегантным способом?

Заранее спасибо!

PS :Я искал на SO "[ускорение] + опции программы последовательности" и "[ускорение -программа -опции] + порядок" (и их варианты )перед публикацией этого, поэтому Заранее извиняюсь, если окажется, что это дубликат.

5
задан scribbleink 2 August 2012 в 00:42
поделиться