CPP-STL:STL备忘
STL备忘(转)
1. string.empty() 不是用来清空字符串,而是判断string是否为空,清空使用string.clear();
2. string.find等查找的结果要和string::npos比较,而不是和-1比较。(各个平台可能不同)
3. 将string转为char * ,用char * t = (char *)s.c_str() ,而不是 char *t =s.begin() 或者 char *t = &s[0] 或者 char *t =s.data();
4. 不要用错string.find ,string::find_first_of ,find和find_first_of有本质区别
find是查找子串在string出现的位置
find_first_of是查找第一个匹配目标字符串任何一个字符出现的位置。
(大多数的时候,需要的是find)
5. 用swap技巧来移去string(vector)多余的空间
1 vector<int> v ; 2 ... 3 vector<int>(v).swap(v);
6. 用vector<char>来储存二进制流
7. 了解各种储存bool的优缺点
vector<bool> 第一,它不是一个真正STL容器,第二,它并不保存bool类(Effective STL 18条)
deque<bool> 不连续
vector<char> 太浪费
bitset 不能动态增长
boost::dynamic_bitset 不是标准
8. vector resize()和reserve()分别和size和capacity对应,不要搞错
9. vector 的at方法会进行边界检查,[]操作符则不会
10. 使用iterator的时候,自增或者自减,多使用++iter ,--iter的格式。
11. std::mem_fun/std::mem_fun_ref可以将成员函数用来for_each等方法。
1 std::vector<Employee> emps; 2 std::for_each(emps.begin(), emps.end(), 3 std::mem_fun_ref(&Employee::DoStandardRaise); 4 5 std::vector<Employee*> emp_ptrs; 6 std::for_each(emp_ptrs.begin(), emp_ptrs.end(), 7 std::mem_fun(&Employee::DoStandardRaise));
12. 如何删除?
1 vector: 2 vector<int> v; 3 v.erase(remove(v.begin(), v.end(), 99), v.end()); 4 5 list: 6 list<int> li; 7 li.remove(99);
13. 尽量用成员函数代替同名的算法
14. 循环中删除map元素的写法
1 typedef map<int,int> mymap; 2 typedef map<int,int>::iterator myiter; 3 mymap m; m[1] = 2; m[2] = -1; m[3] = 3; m[4] = 0; m[5] = -5; m[6] = 1; 4 myiter iter = m.begin(); 5 6 while(iter!=m.end()) { 7 if(iter->second<0) 8 m.erase(iter++); 9 else 10 ++iter; 11 }
15. 从ifstream读出一行到string,使用std::getline(ifstream的成员函数getline做不到)
16.警惕string的引用记数技术实现带来的潜在问题1 string greet("Hello, world"); 2 string hi(greet); 3 char *ptr = (char *)hi.c_str(); 4 ptr[0] = 'h'; 5 //两个字符串都被修改。
在多线程之间引用多个有关系的string,可能导致引用计数失效,造成多次删除,或者memory leak.
保险的做法是:
1 string s1("hello") ; string s2 (s1.c_str()); //force copy
17.自定义类放入stl容器中,应注意实现安全的copy ctor和assign operator.尤其是含有指针的class,避免多次删除
18.避免iterator失效,不提取无效的iterator
比如:
1 vector<int> iv; 2 vector<int>::iterator end = iv .end(); 3 for(int i=0;i<10;++i) 4 iv.insert(end,i);
会crash ,因为end指针,随着insert后可能失效
改为:
1 vector<int> iv; 2 for(int i=0;i<10;++i) 3 iv.insert(iv.end(),i);
或者:
1 vector<int> iv; 2 for(int i=0;i<10;++i) 3 iv.push_back(i); //prefer
auto_ptr<int> p(new int[10]); //maybe cause memory leak
21. 多线程下,几个线程如果共同操作一个容器,安全性(锁)应该由用户自己来实现,stl不保证这一点
例如,一个多线程安全的deque
1 template<typename T,class ThreadModel=MultiThread> 2 class CDequePool:private ThreadModel { 3 private: 4 std::deque<T> m_clDeque; 5 //..... 6 public: 7 bool PutData(const T &data) 8 { 9 Lock(); 10 m_clDeque.push_front(data); 11 Unlock(); 12 return true; 13 } 14 //.... 15 }