懒汉的烦恼
使用C++编程时对数据打印输出比较麻烦,需要自行用for循环将vector, list, map等容器的成员一一打印输出。
相比之下Python, Golang等语言就可以直接对所有数据类型打印输出,这对于debug是很友好的特性。
因此,我开发了一个简单的C++库,几乎能够对所有容器直接打印输出,说几乎是因为我们只能对成员可访问可迭代的容器支持这个特性。
支持的类型如下,以及他们的组合类型:
std::pair, std::tuple, std::array, std::deque,
std::forward_list, std::initializer_list, std::list, std::vector,
std::set, std::multiset, std::unordered_set, std::unordered_multiset,
std::map, std::multimap, std::unordered_map, std::unordered_multimap.
ACMer助手
特别的,我们在打ACM比赛或做类似的OJ题目的过程中,需要debug的时候,我们不仅想要打印容器里的值,
而且还想要同时打印出变量名,以便我们在解题时,如果定义了多个容器变量,我们可以知道哪个变量的值使哪一个值,
因此我设计了watch功能。
宏定义watch可以用一下两种方式:
一,用std::cout输出MYOSTREAM_WATCH_TO_STRING生成的字符串:
1
2
|
#include <myostream.h>
#define watch(...) std::cout << MYOSTREAM_WATCH_TO_STRING(std::string, " = ", "\n", "\n\n", __VA_ARGS__)
|
二,直接使用MYOSTREAM_WATCH,坏处是这里定义了一个变量mycout
,这段代码不能在头文件中被多个源文件include:
1
2
3
|
#include <myostream.h>
myostream::ostream mycout(std::cout.rdbuf());
#define watch(...) MYOSTREAM_WATCH(mycout, " = ", "\n", "\n\n", __VA_ARGS__)
|
例如,如下debug代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
#include <vector>
#ifndef ONLINE_JUDGE
#include <myostream.h>
myostream::ostream mycout(std::cout.rdbuf());
#define watch(...) MYOSTREAM_WATCH(mycout, " = ", "\n", "\n\n", __VA_ARGS__)
#else
#define watch(...)
#endif
int main() {
std::vector<int> v{1, 2, 3};
watch(v);
std::tuple<std::vector<int>, std::map<int, std::set<std::string>>,
std::pair<std::string, double>> complex({1, 2, 3},
{{1, {"a", "aa"}},
{2, {"b", "bb"}}},
{"Aya", 88.5});
watch(complex);
return 0;
}
|
在本地编译运行,可以输出:
1
2
3
|
v = [1, 2, 3]
complex = <[1, 2, 3], {1: {a, aa}, 2: {b, bb}}, (Aya, 88.5)>
|
而在线提交,或定义了宏ONLINE_JUDGE后,则什么都不输出。
附录