作用:
它是一个C++解析命令行的库。它使用命令行和配置文件对程序选项进行设置。该库有错误检查机制,它的选项值可从命令行,配置文件以及环境变量中提取。
要解析一个命令行选项,需要以下三步:
1.定义命令行选项。取名且设置值。若一个命令行选项解析为键/值对,还需要设置值的类型,比如是一个字符串还是一个数字
2.用解析器去解析命令行。从main()的两个参数中获取命令行,argc与argv
3.存储由解析器解析好的命令行选项。boost.program_options库从std::map中派生了一个类可用来存储命令行选项的键/值对。随后,可检查哪个选项已经被存储以及它们的值是什么
样例:
#include <boost/program_options.hpp>
#include <iostream>
using namespace std;
using namespace boost::program_options;
void on_age(int age)
{
std::cout << "On age: " << age << "\n";
}
int main(int argc, const char *argv[])
{
try
{
options_description desc{ "Options" };
desc.add_options()
("help,h", "Help screen")
("pi", value<float>()->default_value(3.14f), "Pi")
("age", value<int>()->notifier(on_age), "age");
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);
if (vm.count("help"))
std::cout << desc << '\n';
else if (vm.count("age"))
std::cout << "Age: " << vm["age"].as<int>() << '\n';
else if (vm.count("pi"))
std::cout << "Pi: " << vm["pi"].as<float>() << '\n';
}
catch (const error &ex)
{
std::cerr << ex.what() << '\n';
}
}
输出:

因此,要使用Boost.ProgramOptions,需要包含头文件boost/program_options.hpp,以及在编译时要添加类似的库目录boost_1_62_0\lib64-msvc-12.0以包含lib文件。使用命令空间:boost::program_options
类boost::program_options::options_description用来描述命令行。该类型的对象会写入类似std::cout流用来显示可变命令行的选项(上例中.\test.exe -h所显示的)。字符串传入该结构中充当命令行名字的角色。boost::program_options::options_description它定义了一个成员函数add()来接收本身类型的参数。可调用该函数来描述每个命令行选项。上例中调用add_options()来做这件事情,但不是每条命令行选项都用它来做,只是它用起来更方便而已。
add_options()返回一个代理对象用来代表类boost::program_options::options_description的一个对象。该代理对象的类型没毛病,更有意思的是该代理对象简化定义了许多命令行选项。它使用operator()重载函数来得到想要的数据去定义一个命令行。该重载操作会返回一个引用给代理对象,它允许重复调用operator()。
上例中在代理对象options_description的帮助下定义了三个命令行选项:
第一个命令行是:--help。该命令行描述设置为“Help screen”。该选项是一个开关,不是键值对。在命令行设置--help或忽略它。不可能给--help设置一个值。
需要注意的是第一个传往operator()的字符串是“help,h”。可为命令行选项指定短的名字。短名只由一个字母构成且在逗号后面。因此,现在输入--help或者输入-h都能显示help选项。
除了--help,还有两个命令行选项,--pi和--age。它们不是开关,它们是键值对。--pi和--age都希望能够设置一个值。
传入boost::program_options::value_semantic类型的对象指针作为operator()的第二个参数来定义一个选项的键值对。不需要直接访问boost::program_options::value_semantic。可使用辅助函数boost::program_options::value()来创建一个boost::program_options::value_semantic类型的对象。boost::program_options::value()会返回该对象的地址,传入operator()的代理对象。
boost::program_options::value()是一个函数模板把命令行选项类型作为模板参数。因此,命令行--age希望得到一个整型以及--pi希望得到一个浮点数。
从boost::program_options::value()返回的对象提供了一些成员函数。比如,default_value()用来设定默认值。比如如果没有在命令行再设置--pi,则默认就设置为了3.14
notifier()链接一个函数到命令行选项的值。随后命令行选项的值会调用该函数。上例中,函数on_age()与--age相连。若命令行选项--age被用来设置一个age,则该age会被传入on_age()后写入标准输出流。
使用类似on_age()的函数来处理数值是可选的。由于还可以使用其他方式来访问数据所以就不一定非要用notifier()。
所有的命令行选项定义后,就需要使用一个解析器了。上例中,辅助函数boost::program_options::parse_command_line()被调用来解析命令行。函数使用argc与argv参数来定义命令行以及desc用来存储选项描述符。
boost::program_options::parse_command_line()以boost::program_options::parsed_options类型的对象的方式返回解析的命令行选项。一般不用直接访问这个对象,而是将它们传入函数boost::program_options::store()中使用容器将它们保存起来。
上例中,传入vm作为boost::program_options::store()的第二个参数,vm是一个boost::program_options::variables_map类型的对象,该对象由std::map<std::string, boost::program_options::variable_value> 派生而来的。并且,因此它也会提供与std::map相同的函数。比如,可以调用count()来检查某个命令行选项是否已经被使用且被保存在容器中。
在上例中,在count()被调用以及vm被读取之前,boost::program_options::notify()被调用了。该函数会触发其他函数的调用,比如on_age(),它是被notifier()函数链接到一个值的。没有boost::program_options::notify()函数,on_age()不会被调用。
vm可用来检查命令行选项是否存在容器中,且可用来读取设置给命令行选项的值。vm的类型是boost::program_options::variable_value,它是一个在内部使用了boost::any的类。
因此,可以从它的成员函数value()中获取到boost::any类型的对象。
上例中,调用as(),而不是value(),是因为该成员函数会将命令行选项的值转换成模板参数传入的类型.as()使用boost::any_cast()来进行类型转换。
一定要确保传入as()的类型与命令行选项的类型匹配。比如,上例中,命令行选项--age希望设置为一个整型值,因此int型必须作为模板参数类型传给as().
解释结果:
.\test.exe
在这种情况下,显示的是Pi:3.14。是因为命令行中没有设置参数为--pi,也因此显示的为默认值。
.\test.exe --pi 3.1415
使用--pi参数设置值时
.\test.exe --pi 3.1415 --age 29
使用了--pi以及--age设置值时。当boost::program_options::notify()被调用时,第一行On age: 29被写入;因为它触发了on_age()函数的执行。而--pi则没有输出,因为程序使用else if语句导致不再执行--pi。
.\test.exe -h
可查看所有的命令行选项。
可使用两种方式查看--help与-h。而--pi则是显示了默认的属猪。命令行选项以及它们的描述符都自动格式化了。只需要将类型为boost::program_options::options_description的对象写入标准输出流即可。
.\test.exe --age
由于--age选项没有设置具体的值。因此boost::program_options::parse_command_line()抛出异常boost::program_options::error。该异常被捕获到,因此一个错误消息写入标准输出流。
boost::program_options::error从std::logic_error派生而来。
Boost.ProgramOptions自定义了一些额外的异常类,都是派生自boost::program_options::error。其中一个异常就是boost::program_options::invalid_syntax,它就是上例中抛出的异常,在没有给--age设置一个值时。
---------------------------------------------------------------------------------------------------------20170728 end.