什么是boost :: program_options :: notify()?

时间:2011-08-19 18:15:07

标签: c++ boost

这个问题是关于C ++ Boost program_options库的。

所有教程都非常明确,我应该在完成的变量图上调用notify(),但我不确定这对我来说实际上是做什么的。评论它似乎没有任何影响,文档没有详细说明:

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

其他消息来源表明它运行“用户定义”功能。如果是这样,这些功能如何注册,他们做了什么?他们可能会抛出异常吗?

3 个答案:

答案 0 :(得分:23)

notify()member function of value_semantic。它是一个钩子,一旦确定了一个选项的最终值,就可以自动完成应该对该选项采取的任何动作,并将其封装在自己的函数中。这可以防止代码具有一个作用于每个选项的长函数。随着可能的选项的增长,这种程序代码可能变得难以处理。

您可以看到an example of setting a notify function in the Boost manual

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&amp; your_function,传递“email”选项的值   作为论点。

答案 1 :(得分:4)

当你提到&#34; functor&#34; ...

时,我认为你走在正确的轨道上

通过将其参数传递给某个对象的方法来处理选项是很常见的。如果您可以将方法包装为notifier()将接受作为参数的内容,则可以使用通知程序更直接地执行此操作。你可以。 (如果boost :: function有办法这样做,我对它不够熟悉(而且我现在懒得去研究它) - 以下使用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
    ;

答案 2 :(得分:0)

我喜欢直接查看源代码。所以,给你:https://github.com/boostorg/program_options/blob/develop/include/boost/program_options/variables_map.hpp#L52

/** Runs all 'notify' function for options in 'm'. */
BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m);

因此,它运行 notify()variables_map 的所有 m 函数,std::map<std::string, variable_value>std::string 的包装器,并包含来自命令选项的映射(如 { {1}}s) 到 variable_values(任何类型)。

现在 this answer by @Conspicuous Compiler 有更多上下文,所以去阅读它。除了源代码,看看他的回答对我有帮助。

此外(OP 已经知道,但这是针对其他人的),这里有一个关于如何使用 <boost/program_options.hpp> 模块的介绍性 Boost 教程:https://www.boost.org/doc/libs/1_75_0/doc/html/program_options/tutorial.html.真的有点“手摇”。他们不希望您知道这些特定功能的真正作用。他们只想让您知道如何遵循模式并使用库,正如他们在说:

<块引用>

接下来,对 storeparse_command_linenotify 函数的调用导致 vm 包含在命令行中找到的所有选项。

(参考以下示例中的代码):

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

当你调用 add_options() 函数时,他们正在用 C++ 做一些非常奇特的黑魔法 vudu。

这是他们的基本教程示例的完整上下文:

example/first.cpp

// Copyright Vladimir Prus 2002-2004.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

/* The simplest usage of the library.
 */

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

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

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

        po::options_description desc("Allowed options");
        desc.add_options()
            ("help", "produce help message")
            ("compression", po::value<double>(), "set compression level")
        ;

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

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

        if (vm.count("compression")) {
            cout << "Compression level was set to " 
                 << vm["compression"].as<double>() << ".\n";
        } else {
            cout << "Compression level was not set.\n";
        }
    }
    catch(exception& e) {
        cerr << "error: " << e.what() << "\n";
        return 1;
    }
    catch(...) {
        cerr << "Exception of unknown type!\n";
    }

    return 0;
}