这个问题是关于C ++ Boost program_options库的。
所有教程都非常明确,我应该在完成的变量图上调用notify()
,但我不确定这对我来说实际上是做什么的。评论它似乎没有任何影响,文档没有详细说明:
http://www.boost.org/doc/libs/1_47_0/doc/html/boost/program_options/notify.html
其他消息来源表明它运行“用户定义”功能。如果是这样,这些功能如何注册,他们做了什么?他们可能会抛出异常吗?
答案 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_value
s(任何类型)。
现在 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.真的有点“手摇”。他们不希望您知道这些特定功能的真正作用。他们只想让您知道如何遵循模式并使用库,正如他们在说:
接下来,对 store
、parse_command_line
和 notify
函数的调用导致 vm
包含在命令行中找到的所有选项。
(参考以下示例中的代码):
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
当你调用 add_options()
函数时,他们正在用 C++ 做一些非常奇特的黑魔法 vudu。
这是他们的基本教程示例的完整上下文:
// 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;
}