Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Boost program_options проблема с notifier, Особенности notifier в program_options 
V
    Опции темы
Zerstroer
Дата 22.6.2012, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Доброго времени суток!
Осваиваю boost program_options. Решил выбросить свой старый велосипед и написать новый обработчик параметров командной строки с использованием boost.
Нагуглил себе в помощь несколько понятных мануалов "для самых маленьких" (официальные доки по program_options осваиваются с большим трудом).
Мне самым понятным показался вот этот.
В общем, такая проблема:
Есть перечень взаимоисключающих параметров, т.е. в командной строке должен использоваться только один из них, в противном случае - должен ругаться. 
Пытаюсь реализовать через штуку под названием notifier. 
А именно:
Для каждого из взаимоисключающих аргументов в notifier устанавливаю вызов функции checkConflict. Она работает с полем класса - bool-флагом, который контролирует, что бы не более одного параметра оказалось определено.
В общем, я не знаю, как правильно передать её в notifier. Может ли она быть не статической? Как её правильно определить и использовать? Можно ли это решить с помощью boost::bind?
Если она статическая - при компиляции возникает ошибка использования поля класса parameterAlreadySet в статической функции.
Есть ли вообще более оптимальный способ решения моей задачи?
Вот мои примеры (для сокращения кода выкинул обработку исключительных ситуаций):

ArgumentsAnalyzer.h
Код


#include <string>
#include <boost/program_options.hpp>

using namespace std;

class ArgumetsAnalyzer {
public:
    ArgumetsAnalyzer(int argc_, char** argv_);    
    /**
     * Функция возвращающая значение из командной строки
     */
    template <typename ReturnType>    
    ReturnType getParameterValue(const string valueName){
        return parsingResult[valueName].as<ReturnType>();
    }               
private:
     /**
     * Описание всех возможных аргументов из консоли     
     */
    boost::program_options::options_description optionsDescription;
    /**
     * Хранится результат разбора командной строки
     */
    boost::program_options::variables_map parsingResult;      
    
    /**     
     * Служебная функция для проверки на конфликт взаимоисключающихся опций, объявленых по умолчанию     
     */
   /*static*/ void checkConflict(const bool value){
        if (value) {
            if (ArgumetsAnalyzer::parameterAlreadySet&&value) {
                cout << "More than one mutually exclusive parameter set!\n";
                //throw ArgumentsAnalyzerException("More than one mutually exclusive parameter set!");
            } else {
                ArgumetsAnalyzer::parameterAlreadySet = true;
            }                
        }    
    }        
    /**
     * Флаг контролирующий, был ли установлен хотя бы один из взаимоисключающихся параметров
     */
    bool parameterAlreadySet;
};


ArgumentsAnalyzer.cpp
Код

#include "ArgumentsAnalyzer.h"

ArgumetsAnalyzer::ArgumetsAnalyzer(int argc_, char** argv_){
    parameterAlreadySet = false;
    namespace po = boost::program_options;
    optionsDescription.add_options()    
        ("help,h", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(checkConflict), "show help message")        
        ("start,S", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(checkConflict), "start application in the work mode")
        ("debug,D", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(checkConflict), "start application in the debug mode")
        ("test,T", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(checkConflict), "start application in the test mode")    
    ;            
    po::store(po::command_line_parser(argc_, argv_).options(optionsDescription).run(), parsingResult);
    po::notify(parsingResult);       
}


main.cpp
Код

#include <cstdlib>
#include <iostream>
#include "ArgumentsAnalyzer.h"
using namespace std;

int main(int argc, char** argv) {
    ArgumetsAnalyzer argA(argc, argv);
    if (argA.getParameterValue<bool>("help")) {
        cout << "Help вызван!" << endl;
    }    
    return 0;
}







--------------------
In silico
PM MAIL ICQ   Вверх
Zerstroer
Дата 25.6.2012, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Наверное пост оказался слишком емким и неясным...
Проблему получилось решить самостоятельно.
Решение пришло с использованием boost::bind
Использовал вызов метода класса так (не верно):

Код

("help,h", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(checkConflict), "show help message")    


С использованием bind (верно):

Код

("help,h", po::value<bool>()->zero_tokens()->implicit_value(false)->notifier(boost::bind(&ArgumentsAnalyzer::checkConflict, this, _1)), "show help message")    


Надеюсь, кому-нибудь на что-нибудь сгодится...




--------------------
In silico
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0408 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.