天天看點

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)多餘的空間

   vector<int> v ;

   ...

   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等方法。

 std::vector<Employee> emps;

 std::for_each(emps.begin(), emps.end(),

        std::mem_fun_ref(&Employee::DoStandardRaise);

 std::vector<Employee*> emp_ptrs;

 std::for_each(emp_ptrs.begin(), emp_ptrs.end(),

              std::mem_fun(&Employee::DoStandardRaise));

12. 如何删除?

vector:

 vector<int> v;

 v.erase(remove(v.begin(), v.end(), 99), v.end());

list:

 list<int> li;

 li.remove(99);

13. 盡量用成員函數代替同名的算法

14. 循環中删除map元素的寫法

typedef map<int,int> mymap;

typedef map<int,int>::iterator myiter;

mymap m;    m[1] = 2;    m[2] = -1;    m[3] = 3;    m[4] = 0;    m[5] = -5;    m[6] = 1;

myiter iter = m.begin();

    while(iter!=m.end())    {

        if(iter->second<0)   

            m.erase(iter++);

        else    

            ++iter;

    }

15. 從ifstream讀出一行到string,使用std::getline(ifstream的成員函數getline做不到)

16.警惕string的引用記數技術實作帶來的潛在問題

string greet("Hello, world");

string hi(greet);

char *ptr = (char *)hi.c_str();

ptr[0] = 'h';

兩個字元串都被修改。

在多線程之間引用多個有關系的string,可能導緻引用計數失效,造成多次删除,或者memory leak.

保險的做法是:

string s1("hello") ; string s2 (s1.c_str()); //force copy

17.自定義類放入stl容器中,應注意實作安全的copy ctor和assign operator.尤其是含有指針的class,避免多次删除

18.避免iterator失效,不提取無效的iterator

比如:

vector<int> iv;

vector<int>::iterator end = iv .end();

for(int i=0;i<10;++i)

    iv.insert(end,i);

會crash ,因為end指針,随着insert後可能失效

改為:

    iv.insert(iv.end(),i);

或者:

    iv.push_back(i); //prefer

19. 不要把std::auto_ptr用于數組指針

auto_ptr<int> p(new int[10]); //maybe cause memory leak

20. 不要直接修改set,map的鍵值,如果要修改,先erase,再insert.

21. 多線程下,幾個線程如果共同操作一個容器,安全性(鎖)應該由使用者自己來實作,stl不保證這一點

例如,一個多線程安全的deque

template<typename T,class ThreadModel=MultiThread>

class CDequePool:private ThreadModel {

  private:

   std::deque<T> m_clDeque; 

//.....   

  public:

   bool PutData(const T &data)

   {

    Lock();

    m_clDeque.push_front(data);

    Unlock();

    return true;

   }

//....

}