boost库开发笔记(五):boost库杂记
记录了boost库一些特别的设计。
boost::program_options
命令行解析:基本类型支持
boost::program_options
可以用于解析命令行参数,常常被用于解析项目运行命令、配置文件、环境变量等到boost::program_options::variables_map
,这个map是一个string-boost::program_options::variable_value
的键值对集合,variable_value.as<T>()
方法能够将其转换到基本数据类型,以及std::vector<T>
以及自定义结构体等,见下文。
一个简单实例如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using namespace std;
namespace program_options = boost::program_options;
int main(int argc, char* argv[]){
//创建解析对象
try{
program_options::options_description pod("test options");
pod.add_options() //添加解析选项,在命令行中只需要-h或者--help
("help,h", "Show Help Info")
("showNum,s", program_options::value<int>()->default_value(10), "Set Int Num")
("outputName,o", program_options::value<std::string>(), "Set File Name");
//创建解析结构
program_options::variables_map vm;
//命令行按选项解析
program_options::store(program_options::parse_command_line(argc, argv, pod), vm);
//更新vm捕获的选项
program_options::notify(vm);
if(vm.count("help")) //存在-h参数
cout << "All Options: " <<pod << endl; //支持直接打印选项
if(vm.count("showNum")){
int num = vm.at("showNum").as<int>();
cout << "Num: " << num << endl;
}
if(vm.count("outputName")){
string name = vm.at("outputName").as<std::string>();
cout << "Name: " << name << endl;
}
//打印program_options::variables_map
for(const auto& pos : vm){
if(pos.first != "showNum")
cout << pos.first << "-" << pos.second.as<std::string>() << endl;
else
cout << pos.first << "-" << pos.second.as<int>() << endl;
}
}
catch(program_options::error &e){
cerr << "Error: " << e.what() << endl;
}
return 0;
}
测试: 1
2
3
4
5
6
7
8
9
10
11
12
13.\test3.exe -s 10 -o "1233333333" -h
#输出:
All Options: test options:
-h [ --help ] Show Help Info
-s [ --showNum ] arg (=10) Set Int Num
-o [ --outputName ] arg Set File Name
Num: 10
Name: 1233333333
help- #无设置为空
outputName-1233333333 #无默认值时该项缺省
showNum-10
STL(vector)与自定义结构支持
除了string、int、double/float、long
等基本数据类型支持,boost::program_options
还直接支持解析到vector<T>
类型:
1
2
3
4
5
6
7
8
9
10
11pod.add_options() //添加解析选项,在命令行中只需要-h或者--help
("help,h", "Show Help Info")
("outputName,o", program_options::value<std::string>(), "Set File Name");
//....解析如上
if(vm.count("vp")){
vector<double> vp = vm.at("vp").as<vector<double>>();
for(const auto& pos : vp){
cout << pos << " ";
}
}
测试: 1
2
3.\test3.exe -v 1.2 -v 2.4 -v 3.6
#输出:
1.2 2.4 3.6
对于自定义类型,只要能通过std:istream
序列化结构体,boost::program_options
就能够支持结构体转换:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using namespace std;
using namespace cv;
namespace program_options = boost::program_options;
struct Test{
cv::Point point;
int num;
void printInfo(){
cout << "Info: " << point.x << point.y << num << endl;
}
};
std::istream& operator>>(std::istream& input, Test& test){
char ch; //吞掉命令行的逗号间隔
input >> test.point.x >> ch >> test.point.y >> ch >> test.num;
return input;
}
int main(int argc, char* argv[]){
try{
program_options::options_description pod("test options");
pod.add_options()
("help,h", "Show Help Info")
("SelfStruct,t", program_options::value<Test>());
program_options::variables_map vm;
program_options::store(program_options::parse_command_line(argc, argv, pod), vm);
program_options::notify(vm);
if(vm.count("help"))
cout << "All Options: " <<pod << endl;
if(vm.count("SelfStruct")){
Test test = vm.at("SelfStruct").as<Test>();
test.printInfo();
}
}
catch(program_options::error &e){
cerr << "Error: " << e.what() << endl;
}
return 0;
}
测试: 1
2
3.\test3.exe -t 1,2,3
#输出:
Info: 123
boost::circular_buffer
std::queue
能模拟队列,但是其长度是无限的,必须手动维护计数和入队出队才能维持定长特性,而且不支持随机存储访问;boost库提供了一种环形缓冲区,类似定长的deque结构,支持push_back
和push_front
,当尾插或者头插超过定长时,能自动弹出相反方向(即尾插越界时弹出头部、头插越界时弹出尾部)元素,且支持随机访问,基本接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using namespace std;
int main(){
boost::circular_buffer<int> cb(4); //定长4
cb.push_back(1);
cb.push_front(2);
cb.push_back(3);
cb.push_back(4);
cout << cb.size() << cb.capacity() << endl; //size:2 capacity:4
//随机访问
for(const auto& pos : cb){
cout << pos << endl; // 2 1 3 4
}
cb.push_back(5);
//随机访问
for(const auto& pos : cb){
cout << pos << endl; //1 3 4 5
}
//头部、尾部、是否满、是否空等接口
cout << cb.front() << cb.back() << cb.full() << cb.empty() << endl;
return 0;
}
自定义数据类型支持
boost::circular_buffer
支持所有基本数据类型,也支持标准库STL包括vector
、list
、deque
等,基本涵盖基本需求,也支持自定义结构体或类,只要提供相应的拷贝构造/拷贝赋值或移动赋值函数即可,此外可以使用std::sort
对环形缓冲区自定义排序(虽然这破坏了FIFO特性):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using namespace std;
struct Person{
int age;
string name;
Person(int age, string name): age(age), name(name){}
void printInfo() const{
cout << age << " " << name << endl;
}
};
bool myCmp(const Person& p1, const Person& p2){
return p1.age > p2.age;
}
int main(){
boost::circular_buffer<Person> cb(4);
cb.push_back(Person(18, "Eden"));
cb.push_back(Person(19, "Eden"));
cb.push_back(Person(20, "Eden"));
cb.push_back(Person(21, "Eden"));
std::sort(cb.begin(), cb.end(), myCmp); //sort自定义排序
cb.push_back(Person(22, "Eden"));
cout << cb.size() << endl;
for(const auto& pos : cb){
pos.printInfo(); //20 19 18 22
}
return 0;
}