Подтвердить что ты не робот

Что такое boost:: program_options:: notify()?

Этот вопрос касается библиотеки program_options С++ Boost.

Все учебники очень понятны, что я должен называть notify() на моей заполненной карте переменных, но я не уверен, что это на самом деле делает для меня. Комментирование этого не показало никакого эффекта, и документация не вдавалась в детали:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost/program_options/notify.html

Другие источники предполагают, что он выполняет "пользовательские" функции. Если да, то как регистрируются эти функции и что они делают? Могут ли они выбрасывать исключения?

4b9b3361

Ответ 1

notify() является функцией-членом value_semantic. Это крючок, который предоставляется так, что, как только окончательное значение параметра определяется, любое действие, которое следует предпринять с этой опцией, может быть выполнено автоматически и инкапсулировано в его собственную функцию. Это не позволяет коду иметь одну длинную функцию, которая действует на каждый из параметров. По мере роста возможных вариантов такой процедурный код может стать громоздким.

Вы можете увидеть пример установки функции уведомления в руководстве Boost:

options_description desc;
desc.add_options()
    ("compression", value<int>()->default_value(10), "compression level")
    ("email", value< vector<string> >()
        ->composing()->notifier(&your_function), "email")
    ;

В этих объявлениях указывается, что значение по умолчанию для первого параметра 10, что второй вариант может появляться несколько раз и все экземпляры должны быть объединены, и после того, как синтаксический анализ будет выполнен, библиотека будет call function & your_function, передавая значение опции "email" как аргумент.

Ответ 2

Я думаю, что вы на правильном пути, когда упоминаете "функтор"...

Это довольно часто для опции, которую нужно обработать, передав ее аргумент некоторому методу объекта. Это можно сделать более непосредственно с помощью уведомлений, если вы можете обернуть метод во что-то, что notifier() примет в качестве аргумента. И вы можете. (Если функция boost:: имеет способ сделать это, я недостаточно хорошо знаком с ней (и мне слишком ленив, чтобы изучить ее сейчас) - следующее использует подпрограммы в функции заголовка из STDLIB.)

Пример:

Один из ваших вариантов: --config-file, содержащий строковый аргумент, который указывает путь к файлу конфигурации, отличному от стандартного. У вас есть класс под названием ConfigParser. Без уведомлений ваш код может выглядеть примерно так:

ConfigParser *cp = new ConfigParser();
std::string cp_path;
desc.add_options()
    ("config-file", value<std::string>(&cp_path)->default_value("~/.myconfig"), "Config File")
    // ... the rest of your options
    ;

cp->setPath(cp_path);

С помощью уведомлений:

#include <functional>

ConfigParser *cp = new ConfigParser();
desc.add_options()
    ("config-file", value<std::string>()->default_value("~/.myconfig")->notifier(std::bind1st(std::mem_fun(&ConfigParser::setPath), cp)), "Config File")
    // ... the rest of your options
    ;