C++标准模板库(STL)常用介绍

1. 输入输出

C++既可以用C的scanf和printf,也可以用新增的的cin与cout,后者速度慢

1.1 C程序中输入输出

int a;
scanf("%d",&a);
printf("%d",a);

1.2 C++输入输出

int a;
cin >> a;
cout << a;

1.3 输入输出多个变量

int a,b,c;
cin >> a >> b >> c;
cout << a << b << c;

1.4 新增的换行

cout << endl;

2. algorithm头文件下常用函数

2.1 max()、min()、abs()/fabs()

#include<stdio.h>
#include<algorithm>
using namespce std;
int main(){
  int x = 1, y = -2;
  printf("%d %d\n", max(x, y), min(x, y));   // 输出  1 -2
  printf("%d %d\n", abs(x), abs(y)); 				 // 输出  1  2
  return 0;
}

​ max(x, y)、min(x, y) 分别返回x和y中的最大、最小值,且参数必须是两个(可以是浮点数),参数为三个时可以写成max(x, max(y, z))

​ abs() 则是返回绝对值,需要注意的是只能传入整数,而浮点数对应的绝对值函数是 fabs()

2.2 swap()

int x = 1, y = 2;
swap(x, y);
cout << x << y;     // 输出 2 , 1 交换 x y 的值

2.3 reverse()

reverse(it, it2) 注意的是左闭右开原则 , 翻转的范围是 [it, it2) . 可以方便的记后面加记就是反转几个

int a[10] = {1, 2, 3, 4, 5, 6, 7};
string s = "abcdefg";
reverse(a, a+4);   // 输出 4 3 2 1 5 6 7
reverse(s, s+4);   // 输出 "dcbaefg"

2.4 next_permutation()

输出序列在全排列中的下一个序列

int a[3] = {1, 2, 3};
do{
  cout << a[0] << a[1] << a[2];
}while(next_permutation(a, a+3));

// 输出
//123
//132
//213
//231
//312
//321

注意 若达到全排列最后一个 返回的是false 对于循环退出判断很友好

2.5 fill()

类似memset ,但是不同于fill可以赋值数组类型对应范围中任意值

int a[5] = {1, 2, 3, 4, 5};
fill(a, a+5, 233);
// a[5] 变成 233,233,233,233,233

2.6 sort()

sort(首地址, 尾地址的下一个地址, 比较函数) 这里比较精髓的是比较函数的设定 可以不填,默认是非递减排列

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

int main(){
    int a[]={2,3,5,0,-1,4,1};
    sort(a,a+7);
    for(int i=0;i<7;i++)
        cout<<a[i]<<" ";   // 输出 -1 0 1 2 3 4 5
    return 0;
}

2.6.1 比较函数cmp

若对字符排序, 比较的是字典序greater<type>()非递增 less<type>()非递减

对于自定义的cmp 它的返回值为bool类型,简单来记 return a > b, 左边大 就是从大到小非递增,反过来小于号就是非递减

bool cmp(type a, type b){
  if(xxx) return a > b;
  return a < b;
}

同样适用于结构体,**vector, string, deque **

而set,map利用了红黑树实现,内部本身有序,不能使用sort

2.7 lower_bound() 和 upper_bound()

这两个必须用在有序数组或者容器之中。

lower_bound(first, last, val) 寻找[first, last) 依然是左闭右开原则,在此范围内第一个值大于等于val的元素的位置,若是数组,返回指针,若是容器,返回迭代器。(upper则是小于等于…)

用的较少且相对简单,不赘述。

3. vector

vector翻译为向量,叫做变长数组更好理解。

3.1 vector构造

vector<type> name;//定义一个空vector,type可以使int/double/char/结构体/其他容器
vector<int> v(3);//定义一个3个大小的vector,初始为0
vector<int> v1(3,6);//定义一个3个大小的vector,初始为6
vector<int> v2{1,2,3,4,5};//定义一个vector,数字为1,2,3,4,5
vector<vector<int>> name; //定义一个元素为vector的vector 类似变长二维数组
vector<type> arrName[size]; // 定义type类型的size大小的数组 arrName[x] 每个元素都是vector容器

3.2 访问vector

3.2.1 通过索引

vector<int> v{1,2,3,4,5};
cout << v[1]; // 取索引为1的 为2
cout << v.at(1); // 取索引为1的值 此处为2

3.2.2 通过迭代器

vector<int>::iterator it;
//还是上面的例子 那么:   *(it + i) == v[i] == (v.begin()+i)

3.3 常用函数方法

3.3.1 push_back() 往后添加内容

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for(auto x:v) cout << x; //输出 12345

3.3.2 pop_back() 从后弹出/删除尾元素 时间复杂度O(1)

vector<int> v{1, 2, 3, 4, 5};
v.pop_back();
// 剩下 1, 2, 3, 4

3.3.3 resize() 重置大小

v.resize(10);//不赋值默认为0

3.3.4 clear() 清空vector所有元素 时间复杂度O(N) N为元素个数

v.clear()

3.3.5 insert(it, x) 在迭代器it处插入元素x 时间复杂度O(N)

vector v{1, 2, 3, 4, 5};
v.iinsert(v.begin() + 2, -1);
// 得到 1 2 -1 3 4 5

3.3.6 erase() 删除元素 可以是单个 也可以是 [区间) (左闭右开)

v.erase(v.begin());   //删除第一个元素
v.erase(first, last); //删除 [first, last) 左闭右开!

3.3.7 获取第一个元素,获取最后一个元素

/**获取第一个元素*/
cout << v.front();
cout << v[0];
cout << *v.begin();
/**获取最后一个元素*/
cout << v.back();
cout << v[v.size()-1];
cout << *--v.end();

3.3.8 find ( ) 函数

  • algorithm中的find()函数,返回值是目标元素的下标,找不到时返回值为迭代器结尾
string = "hello";
find(s.begin(), s.end(), 'o'); // 等于最后一个元素

3.3.9 循环遍历相关

vector<int> v{5,1,2,5,4,0,-1};
for(int i=0;i<v.size();i++) cout<<v[i];   //for循环

for(vector<int>::iterator it=v.begin();it!=v.end();it++) 
  cout << *it;//迭代器循环

for(auto it=v.begin();it!=v.end();it++) cout << *it;//迭代器简化循环

for(auto x:v) cout << x;//c++11新特性

4. set 和 unordered_set

是一个内部自动有序且不含重复元素的容器。

set<type> name;    // type类型的 有序
unordered_set<type> name2;   //哈希结构 无序 更快

cout<<s.size();   // 计算set长度
// 遍历
for(auto x:s)    
    cout << x;

for(auto it=s.begin(); it!=s.end(); it++)  // 通过迭代器 不能用  *(it + i)
    cout<<*it;

其他 insert() find() erase() clear() 用法与上面vector一致 👆

5. string

存放字符的字符串 类似C里头的字符数组 char str[]

5.1 简单使用

5.1.1 定义

//C中定义字符串以及打印//
char *ch="abcdef";
for(int i=0; ch[i]!='\0'; i++) cout << *(ch+i); // 输出abcdef
//C++//
string s="asdfg";
s.size() == s.length(); // 都是返回长度
cout << s;   // asdfg

5.1.2 读入字符串

string s;
getline(cin,s);//获取一行数据

5.2 常用函数

5.2.1 find() 相关

find()

string str1, str2;
char c; 
str1.find(str2);   //从串str1中查找时str2,返回str2中首个字符在str1中的地址
str1.find(str2,5); //从str1的第5个字符开始查找str2
str1.find(c);      //在str1中查找字符 c 并返回第一个查找到的地址
str1.find("str2" ,2, 2);     //从str1中的第二个字符开始查找str2的前两个字符

​ ②find_first_of()
​ 函数原型:int find_first_of(char c, int start = 0);
​ 这个用法和①中str1.find(str2)相似,都是返回str2中首个字符在str1中的地址。
但是要特别注意,没有找到时返回值是-1.
​ ③ find_last_of()
​ 函数原型:int find_last_of(char c); 未找到时返回-1。
​ ④ find_not_first_of()
​ 函数原型:size_type find_first_not_of(char ch, size_type index = 0 );
​ 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如 果没找到就返回string::nops。
​ ⑤ find_not_last_of()
​ 函数原型:size_type find_last_not_of(char ch, size_type index = 0 );
​ 在字符串中查找最后一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。 如果没找到就返回string::nops。

5.2.2 operator+=

+=直接把两个string拼接起来

string s;
s += "hello";
s += " world";   // 此时 s = hello world
 
s += 10; // 此时10对应ascii码==换行
int a = 2; // int a加入字符串 需要转为字符
s += (a + '0');

5.2.3 排序

string s="541230";
sort(s.begin(),s.end());  // 012345

5.2.4 erase()函数

和vector一致

// begin是头迭代器,end是尾迭代器 //
string s="5352567";
s.erase(s.begin());//删除第一个
s.erase(--s.end());//删除最后一个

5.2.5 compare operator

==、!=、<、<=、>、>= 比的是字典序的大小

string str1 = "aa", str2 = "aaa", str3 = "abc", str4 = "xyz";
//此时 str1 < str2; 
// str1 != str2;
// str4 >= str3;

5.2.6 substr()函数

//begin() 头迭代器,end() 尾迭代器//
string s="567318340";
s = s.substr(1,3);   // 得673 意思是索引从1开始 往后取3位
s = s.substr(1,-1);  // 索引1 也就是从头开始 取到最后

5.2.7 string::npos

为一个常数,本身为-1,但是为unsigned_int类型 可以认为是其类型的最大值

5.2.8 replace()

str.replace(pos, len, str2) 把str从pos开始,长度为len的子串替换为str2

str.replace(it1, it2, str3) 把str迭代器 [it1, it2) 依旧是左闭右开 替换为str3

5.2.9 访问方式(3种)

1.for循环

string s="5193840";
for(int i=0;i<s.length();i++) cout<<s[i];   ///5193840

2.迭代器

for(string::iterator it=s.begin(); it!=s.end();i t++) cout << *it;
for(auto it=s.begin();it!=s.end();it++) cout << *it;

3.利用C++ 11新特性for循环

for(auto x:s) cout << x;

5.2.10 stoi 函数

stoi(字符串,起始位置,n进制),将 n 进制的字符串转化为十进制

stoi(str, 0, 2); //将字符串 str 从 0 位置开始到末尾的 2 进制转换为十进制
stoi(str); //默认str全转为十进制

5.2.11 atoi( ) 函数

int atoi (const char *str );字符串转换成整型数。

参数str:要进行转换的字符串

返回值:每个函数返回 int 值,此值由将输入字符作为数字解析而生成。 如果该输入无法转换为该类型的值,则atoi的返回值为 0。

5.2.12 c_str ( )

将C++的string转化为C的字符串数组,c_str()生成一个const char *指针,指向字符串的首地址

char *p=s[10];
string a=“hello world”;
strcpy(p, a.c_str());
cout << p; //结果为 "hello world"

5.2.13 strcpy(a, b) 字符串复制

把字符串b 复制到 a

5.2.14 reverse()

reverse() 反转字符串

6. map 和 unordered_map

映射关系 键值对 像python里的字典(map为树状表,unorderedmap为哈希表 更快)

6.1 map<type, type> name

map<int,int> m; //有序 
m[6]=3;
m[5]=2;
m[4]=1;
// 通过迭代器访问
for(auto it=m.begin();it!=m.end();it++)
    cout << it->first << “-” << it->second;
for(auto t:m)
    cout << t.first << "-" << tmp.second;
//输出 4-1 5-2 6-3 按照键的大小 从小到大排序 和set一样内部用红黑树实现

6.2 unordered_map<type, type> name

unordered_map<int,int> m; //无序
m[3]=3;
m[2]=8;
m[1]=9;
//迭代器访问
for(auto it=m.begin();it!=m.end();it++)
    cout<<it->first<<"+"<<it->second<<endl;
for(auto t:m)
    cout<<t.first<<"+"<<t.second<<endl;
// 此时输出为无序(按照某种序的无序)

此外还可以通过下标访问,因为map的健是唯一的

map<char, int> m;
m['a'] = 1;
cout << m['a'];   // 为 1

6.3 其他函数方法

find() erase() size() clear() 都和上述vector,string 用法一致。

7. queue 和 priority_queue

queue为先进先出的队列 priority_queue为优先队列

queue<type> name 定义一个name名type类型的队列

7.1 访问及常用函数

push(x) 将x推进队列

front()访问获得队首元素 back()获得队尾元素

pop()队首元素出队

q.push(2);  // 2
q.push(3);  // 3 2
cout << q.front(); // 2
cout << q.back(); // 3
q.pop(); // 弹出2  队内剩 3
cout << q.front(); // 3

7.2其他函数

empty() size() 也和其他容易的用法一致。

7.3 优先队列的访问

有限队列的定义是和普通队列一样的

但是访问没有front() back() 只能通过 top() 访问队首元素 也就是优先级最高的元素

pop() empty() size() 用法也一致

重点在这 优先级的设置

7.4 优先队列的优先级

priority_queue<int> q 默认写法 优先级就是数字越大、字符字典序越大的优先级越大!

priority_queue<int, vector<int>, less<int>> q

这种写法第二个参数是承载底层数据结构堆(heap)的容器,所以第二个参数vector的数据类型要与第一个参数一致 这里是int 第三个参数则是比较序 less表示数字大优先级大 greater相反

7.5 结构体优先级 及 重构

struct fruit{
    string name;
    int price;
    friend bool operator < (fruit f1, fruit f2){
        return f1.price < f2.price;
    }
};

这里用friend友元重构了小于号< 使结构体fruit会以价格高的为优先级高

同理 若是要价格高的优先级低 则return里 小于改为大于号即可

这里的重构 恰好和sort中cmp的是相反的! sort里return f1.price>f2.price 则是按价格从高到低排序 下面方法则是把重构写成类似cmp

struct cmp{
    bool operator () (fruit f1, fruit f2){
        return f1.price > f2.price;
    }
};

//此时定义优先队列
priority_queue<fruit, vector<fruit>, cmp> q; // 其实效用==greater<fruit>

延伸:重构可以用在其他STL容器(set)定义优先级大幅提升效率

8. deque

双端队列deque <type> name

deque<int> d;
// 前后 push进 pop出与vector一致
d.push_back(1);
d.push_front(4); // 此时d中  4 1
d.pop_back();// 弹出1
d.pop_front(); // 弹出4
//遍历
for(auto tmp:d) cout << tmp;
for(auto it=d.begin();it!=d.end();it++) cout << *it;

同时也支持sort() resize() insert() erase() 用法和其他容器一致

9. stack 栈

9.1 定义栈及简单操作

  • 只能通过top()访问栈顶元素
stack<int> s; // 定义一个 int 型 名为 s 的栈
// push进栈
s.push(2);
s.push(3);
// 获取栈顶的值
cout << s.top(); // 此时为 2
// 出栈一个元素 无返回值
s.pop(); // 弹出2
cout << s.top(); // 此时为3
// 栈的长度
cout << s.size(); // 为 1
// empty()判断栈是否为空
if(s.empty() == true) cout << true;
else cout << false;   // 此时返回false

9.2 进制转换 (十进制转二进制)

利用栈比较经典的做法 除2取余 逆序排列 用栈太合适了

int itob(int decimal)
    {
        stack<int> s;
        int res = 0;
        while (decimal != 0)
        {
            s.push(decimal % 2);
            decimal /= 2;
        }
        while (!s.empty())
        {
            res = res * 10 + s.top();
            s.pop();
        }
        return res;
    }

9.3 sstream 与 字符串与数字互转

stringstream 对象用于输入一行字符串,以 空格 为分隔符把该行分隔开来

  • 字符串转数字

方法1: 利用sstream

 string s="1234";
 int i;
 stringstream ss;
 ss << s;
 ss >> i;

方法2: 直接利用==stoi ()==函数

string s="1234";
int i = stoi(s); // stoi函数 将n进制转为十进制
  • 数字转字符串

方法1: sstream

int a = 1234;
string out;
stringstream ss;
ss << a;
ss >> out;

方法2: C++ 11 最新 to_string() 方法

int a = 1234;
cout << to_string(a);

例题 PAT B1009 可以利用 ssteam 简化 PAT-B1009 说反话 - 字符串反转

10. pair

pair<type1, type2> name; 是将两个元素捆绑成一个元素 成为结构体的替代品 实质都一样

10.1 pair的定义、添加、访问

pair有两个元素 first/second,还需要记住一个自带的make_pair函数

pair<string, int> p;
// 第一种添加方式
pair<string, int> p("xixi", 3);
// 第二种方式
p.first = "haha";
p.second = 123;
// 利用make_pair
p = make_pair("hoho", 5);
// pair的输出
cout << p.first << " " << p.second;

10.2 pair元素的比较

两个pair类型可以直接用 ==、!=、<、<=、 >、 >=

比较规则是先比较first的大小,只有当first相等是才比较second的大小 (默认由小到大排序)

10.3 pair的用法实例 (map转成vector进行排序)

bool cmp(pair<int,int> a,pair<int,int> b){
    return a.first>b.first;
} //比较函数

int main(){
    unordered_map<int,int> m; //无序 哈希结构
    m[6]=3;
    m[5]=2;
    m[4]=1;
    vector<pair<int,int>> v(m.begin(),m.end()); // 把映射关系加入到向量中
    sort(v.begin(), v.end(), cmp); // 排序
    for(auto t:v){
        cout << t.first << t.second << endl;
    }
    return 0;
} 
// 输出
// 63
// 52
// 41

11. list

双向链表 比起vector , list支持快速插入和删除, 但是随机访问比较慢

list<int> l; // 初始化
l.push_back(1); // 尾部输入一个1
l.push_front(3); // 头部输入一个3
// C++11 新增加的emplace 类似于push
l.emplace_front(2);
l.emplace_back(4);
// 插入
l.insert(pos,eN,ele);  // pos开始位置,eN为插入元素数,不填默认1,ele 为插入的元素
// 访问
for(auto t:li) cout << t;
for(auto it=li.begin(); it!=li.end(); it++) cout << *it;

pop_back() pop_front() size() empty() erase() clear() front() back() swap() reverse() sort() 也和其他容器用法一致

12. 文档

更详细的方法查文档

中文:http://c.biancheng.net/stl/ 
英文:http://www.cplusplus.com/reference/stl/ 

13. 万能头文件

嘿 写在最后就是怕一开始就用这个偷懒,其实用到什么打上对应头文件最后看到一列头文件还别有一番感觉,但是…万能头文件确实更方便

#include <bits/stdc++.h>
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这上传的资源中包含一套我工作中常用模板,及不需要MFC支持的excel操作接口,导出函数调用栈(dump stack)接口,可以直接用VS2008运行TestCodeLib.sln来根据unit test来了解用法。 ⑴ 需求(requirements) 重量级的BOOST非常强大,但有时候项目中没有引入它,这时候我们需要自己的模板。 BOOST is very powerful, but some projects have not include BOOST library. So we need out own template type trait library -- it is the responsibility of this lightweight library. 即使BOOST非常强大,但有些常用的功能其也没有,而经常性的代码中又需要这些功能。比如把运行期数据转换为元程序需要的编译期数据。 Even if BOOST is very powerful,it can't still meet all requirements. e.g. convert runtime data into compile period data needed by metaprogramming. /*************************************************************************************************************************************/ ⑵ 益处(advantage) 此泛型抽象了一些常用的业务需求,可以避免大量的重复工作。 它是完全泛型的并且是类型安全的(没有强制类型转换),如果使用错误将导致编译失败,从而提高了正确率(正确性由编译器保证)。 这个的很多模板类型推导不需要C++11的支持,这是一个大的优势(VS2010才开始支持C++11)。 this general library draws out some common business and avoid unnecessary repeat work. it is completed general and type-safe(without any type cast), mistake(s) will cause compile failure, so it improves correctness. In this library , type deduce need't C++11's support, it is big advantage. (VS2010 begin to support C++11) /*************************************************************************************************************************************/ ⑶ 用法(usage) 下载这个后,使用VS打开.\CodeLib\testcase\TestCodeLib\TestCodeLib.sln,直接按F5启动,即可以看到许多单元测试的用法/测试用例的输出。 如果需要使用某功能,可以参考其对应的测试代码的用法。(每个功能文件.\CodeLib\include\MiniMPL\xxx.hpp,都对应一个测试文件.\CodeLib\testcase\MiniMPL\test_xxx.hpp) (这个的使用及修改是完全自由的,只需要保留文件头中的注释即可) usage: download this library, open .\CodeLib\testcase\TestCodeLib\TestCodeLib.sln with VS,you can see many usage/test output of unit test. every feature has according unit test file, it shows its usage. e.g. .\CodeLib\include\MiniMPL\xxx.hpp has according ".\CodeLib\testcase\MiniMPL\test_xxx.hpp" this library is all free, the only requirement is that you need to keep the comments in header file. /*********************************************************************************************************************************************************/ ⑷ 本提供的主要功能介绍: major feature in this lib: ◆ [typeTraits.hpp] ★ 测试类型的基本属性,比如IsConst/IsVoliate/IsRef/isAtomType/isBuildInType/isEnumType/IsIterator/IsPointer/isString/isInnerFloat/isArray/IsBaseDerive/.... ★ 转换类型的基本属性,比如AddConst/AddVoliate/AddRef/AddPointer,..,RemoveConst/RemoveVoliate/RemoveRef/RemovePointer,... 这类功能是元程序的基本支持组件,其它(比如boost)也提供了,但本时提供的检测属性更多。 ☆ detect type property. e.g.IsConst/IsVoliate/IsRef/isAtomType/isBuildInType/isEnumType/IsIterator/IsPointer/isString/isInnerFloat/isArray/IsBaseDerive/.... ☆ convert type basic qualifier,e.g. AddConst/AddVoliate/AddRef/AddPointer,..,RemoveConst/RemoveVoliate/RemoveRef/RemovePointer,... get type traits.e.g.const/voliate/ref/isAtomType/isBuildInType/isEnumType/isString/isInnerFloat/isArray/IsBaseDerive/.... It is base support component of metaprogramming system,it is similiar with BOOST , but this lib provide more. ◆ [typeConvert.hpp] ★ 实现类型的修饰符转换。比如让输出参数类型的修饰符(const/voliate/ref/*)和输入参数类型的修饰符一样。 SameConst/SameVoliate/SameRef/SamePointer/SameAllQualifier/RefAdapter 应用场景:存取结构体的某类成员,当输入参数有某种const/voliate/ref修饰符时,通常要求返回值也有类似的修饰符。 ★ 当把"智能指针/stl迭代器/C指针/前三者嵌套"都视为指针时,其内的最终值(非指针值)是一致的,在模板函数中,某些场景需要取得其最终的非指针值。 应用场景:转发模板函数,如 template<typename T> void transmit(T p) { receive(p); } //void receive(int&); 如果transmit的传入实参p为指针类型(比如smartpointer<vector<int*>::iterator>*或者vector<int*>::iterator), 但是转发的接收函数receive的形参为非指针类型(比如int&),理论上是可以实现转换的。 Get::finalValue接口提供了这种自动的转: template<typename T> void transmit(T p) { receive(Get::finalValue(p)); } ☆ Convert type qualifiers,e.g. addConst/removeConst.. , keep same output qualifier (const/voliate/ref/*) with input type. apply scenario: get member of one structure object. ☆ Think "stlSmartptr<T>/StlContainer<T>::iterator/T*" as pointer, their inner non-pointer value is same. in some scenario, the final non-pointer value is needed. e.g. template<typename T> void transmit(T p) { receive(p); } //void receive(int&); if real paremeter "p" is smartpointer<vector<int*>::iterator>* or vector<int*>::iterator , but needed parameter by "receive" is int&, in theory it is OK. Get::finalValue provide this conversion: template<typename T> void transmit(T p) { receive(Get::finalValue(p)); } ◆ [traverseTypeSet.hpp] ★ C++语法不支持模板函数/模板成员函数作为回调函数。本采用了封装,可以支持模板函数的回调,并且支持最多7个可变参数(可以简易扩充参数个数)。 可以遍历一个TypeList或者枚举值范围CEnumRange,然后以满足条件的类型回调用户的模板函数。 其广泛的应用场景即是把运行期数据以一种非hard-code的方式转化为编译期数据,从而满足元程序对编译期数据的需求。 ☆ C++ doesn't support template-based callback function. this lib package support template-based callback function(MAX 7 various parameters,easy to expand). It can traverse one TypeList or enum value , then call user's template function by suitable type/enum value. This feature converts runtime data into compile data to meet metaprogramming requirement without hard-code way, it is one big advantage. ◆ [functionTraits.hpp] ★ 获取任意类型函数的各种特征,比如函数的所有参数Params_T,返回值类型Return_T,对象类型Object_T(如果是成员函数),第N个参数的类型GetFunctionParam<F,N>, 这些类型都是包含修饰符(const/voliate/ref)的完整类型。 这些组件对于操作函数非常重要。 ☆ get some traits of any function, include all parameter type "Params_T",return type "Return_T", host type "Object_T"(if member-function) , No.x parameter type "GetFunctionParam<F,x>". this type include all signature qualifiers. This component is very important for metaprogramming based on function. ◆ 有时候STL的算法并不好用,经常是为了第三个参数需要自己写一个专用的琐碎的小函数。 虽然可以用std的bind或者boost的lambda,但是对于某些嵌套情况,用起来非常麻烦,这个提供了下面的一些解决方式: sometimes STL algorithm is not good and it needs one traival function object(third parameter) , althrough std::bind/boost::lambda is available, but for some nest case, it is very hard to be used.this library provide below features: [function.hpp] ★ 把既有的多元函数转换为一元函数对象UnaryFunction。它通常应用于泛型(比较/排序/遍历)算法的第三个参数。 ☆ convert existing multi-parameters into unary function, it is general used as 3rd parameter in general algorithm. e.g. stl::for_each [functionobject.hpp] ★ 把一些常用目的的函数封装成函数对象,比如"比较器/测试器" ☆ function object with special abstract targart. e.g. "comparer/Tester" ◆ [functionCreater.hpp] ★ 把多元函数封装为一元函数的帮助函数。(一元函数对象的类型通常不易于书写) ☆ helper function to pack multi-parameters into unary function.(it is hard to write unary function object type) ◆ [paramPackage.hpp] ★ 实现了把任意多个(最多7个,可简易扩充),任意类型的参数封装成一个参数以利于数据传递。 ☆ pack any number parameter (max 7,easy expand) into one parameter . it is easy to transfer. ◆ [classregister.hpp] ★ MFC的动态创建不是泛型的,创造出来的对象必须是CObject的派生类,而且支持的创造方式单一,不够灵活有时候甚至不能满足需求。 本里提供了一个泛型的动态创建方式,可以以多种灵活的方式甚至用户自定义的方式来匿名动态创建对象,创建的对象基类可以由用户指定(必须存在派生关系)。 ☆ like MFC's DYNAMIC_CREATE, but the one of MFC is not general,the instance MUST be drived from class CObject, MFC dynamic creation has only one create way,sometimes it is not enough。 this library provides general dynamic create way, can create object by multiple ways , even customized way.and base class can be specified by user. ◆ [callbackWorker.hpp] ★ 最易于使用的回调函数是无参数的回调函数。 此功能可以把任意多个参数的多元(成员/非成员)函数封装成一个无参数函数,作为简单的回调函数。 ☆ best callback function is non-parameter function. This feature packs multiple-parameter function into one no-parameter function, it is easy to be used as callback function. ◆ [memberPtr.hpp] ★ 以统一的方式实现了任意级数的结构体成员的存和取,比如多级结构体嵌套。例子:a.m_b.m_c.m_d.....m_x,非常易于在模板设计中使用。 ☆ access any level member of structure object by one unified way. e.g:a.m_b.m_c.m_d.....m_x,it is easy to be used in template componment. ◆ [anyObject.hpp] ★ 任意对象类(CAnyObject)。提供模板化的指针操作符,如果不支持用户指定指针类型,则转换结果为NULL,从而保证正确性。 ☆ package any object(CAnyObject), it operator function is template-based. if it doesn't support conversion, it return NULL. ◆ [dataset.hpp] ★ 把STL容器和经典数组封装成统一的形式,在使用上不再区别对待。对于C数组,将会自动检测越界情况。 ★ 可以使用初始化列表对数组,STL容器进行(反复)初始化。例如:vector<int> a={1,2,3,45,2}; ☆ pack STL container and class array into unified object with several same interfaces. ☆ can initialize array/stl container with initalization list repeated. e.g. vector<int> a={1,2,3,45,2}; ◆ [macroLoop.hpp] ★ 当多条语句的差别仅仅是一个数字时,可以利用提供的循环宏简化成一条宏语句,从而简化书写。用法可参见对应的单元测试例子。 ☆ if only one number is different in multiple statements, can use one macro loop to simplify them (one macro statement) usage refer to unit test. ◆ [mathOperator.hpp] ★ 泛型的数学操作符。"equal/lesser/NotBinary/NotUnary/notEqual/lesserEqual/greater/greaterEqual及交换函数swap/swapif" ☆ general math operator. "equal/lesser/NotBinary/NotUnary/notEqual/lesserEqual/greater/greaterEqual and swap/swapif" /*************************************************************************************************************************************/ ⑸ 感谢及借鉴: 本中的占位符[placeHolder.hpp]借鉴于boost,感谢boost的大师们的灵感。 typelist来自loki,但是把命名空间Loki改为MiniMPL以避免频繁的命名域切入/切出,感谢Andrei Alexandrescu的精彩演绎与启发. thanks and borrow: Args [placeHolder.h] comes from BOOST::MPL. thanks for BOOST team. typelist comes from loki lib with tiny modification(rename namespace loki to MiniMPL to avoid field switch frequently).thanks for Andrei Alexandrescu

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值