泛型
1. auto_ptrs
1)auto_ptrs cannot share ownership
2)auto_ptrs are not provided for arrays(auto_ptr 使用operator delete 语义,尽量使用vector 代替数组)
const auto_ptr可以使拷贝auto_ptr 的操作非法。
const auto_ptr<T> pt1(new T);
auto_ptr<T> pt2(pt1); //error;
auto_ptr<T> pt3;
pt3 = pt1; //error;
如果使用auto_ptr, 你的类就必须提供自己的具有正确语义的析构函数,拷贝构造函数和拷贝赋值函数, 或者禁止掉拷贝构造函数和拷贝赋值函数.
2. Iterator Categories
2)Output iterator
3)Forward iterator
4)Bidirectional iterator
5)Random access iterator
Iterator Adapters
1)Reverse Iterators
rbegin() is container::reverse_iterator(end())
rend() is container::reverse_iterator(begin())
2)Insert Iterators
3)Stream Iterators
3. std::cin 和 std::cout
std::basic_ostream<char, std::char_traits<char> >
4. std::remove 和 erase
remove接收指定它操作的元素区间的一对迭代器。它不接收一个容器,所以remove不知道它作用于哪个容器。此外,remove也不可能发现容器,因为没有办法从一个迭代器获取对应于它的容器。remove并不“真的”删除东西,因为它做不到。另外有两种“类似remove”的算法:remove_if和unique
5. 为了让状态性predicate 正常工作, 对算法有哪些必要的要求
2)算法必须以某个已知的顺序将predicate作用到区间的元素上,通常是从第一个到最后一个
6. typename
对有依赖性的名称使用typename
vector<char> v;
char* p = &v[0];
C++标准保证, 如果一个符合标准的序列容器提供operator[],这个运算符必然返回类型T的左值, 而左值是可以取得地址的。
C++标准库要求vector 必须对bool进行特化, 于是作为一个特化模板,vector<bool>不是一个容器,它不符合标准库容器的条件。 实际上,vector<bool>并没有存储bool. &v[x]也取不到元素的地址。
vector 和deque 在结构上的主要区别在于, 这两种容器的内存组织方式不一样, deque 是按页,page 或 块 chunk来分配内存的, 每个page包含固定数目的元素, 他在序列的两端插入元素都很有效率。 相反,vector 分配一块连续的内存,只是在序列的尾端插入元素的时候才有效率。
1)即使在容器的前端,deque也提供了常数时间的insert 和 erase, 而vector 不行。
2)deque使用内存的方式对操作系统更友好。
3)在体积增长方面, 他比vector 更有效率,vector 提供的两个函数,capacity()和reserve(), deque并不需要它们。
4)用vector 替换C style的数组在使用中是安全的, 而且你应该尽量使用vector 或者deque,而不使用数组。
9. vector
vector<int> v;v[0];//不做范围检查, 如果不在有效范围, 行为未定义
v.at(0)//如果不在有效范围, throw std::out_of_range
resize / size:size 指目前容器有多少个元素, resize 则会在容器尾部添加或删除一些元素,用来调整容器的大小。
reserve / capacity:capacity告诉你最少添加多少个元素才会导致容器重分配内存,而reserve在必要的时候总是会使容器的内部缓冲区扩充至更大的容量,以确保至少能满足你所指出的空间大小
只有随机访问迭代器支持<
11. const_iterator
如果不需要对容器的元素作任何改动的时候,最好使用const_iterator
将迭代器转型为指针 &*iter, 先将迭代器解引用,获得容器内对象的直接引用,然后获取它的地址。
13. 函数模板的link种类
避免使用export1)包含模式
2)分离模式
14. empty() 与 size()==0
用empty来代替检查size()是否为0
多个读取者是安全的。多线程可能同时读取一个容器的内容,这将正确地执行。当然,在读取时不能有任何写入者操作这个容器。
对不同容器的多个写入者是安全的。多线程可以同时写不同的容器。
16. 使用“交换技巧”来修整过剩容量
string s;
... // 使用v和s
vector<Contestant>().swap(v); // 清除v而且最小化它的容量
string().swap(s); // 清除s而且最小化它的容量
永远让比较函数对相等的值返回false
18. 判断类型是否为class
template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(…);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};
19.for_each 和 transform
transform 可以将操作的返回值赋给元素
20. 排序算法
sort 内部采用quick sortpartial sort 内部采用 heap sort
stable sort 内部采用 merge sort
21. for_each
Function for_each (InputIterator first, InputIterator last, Function f);
对区间[first, last)的每一个元素调用f(elem), 并返回 f 的一个副本
* f 的任何返回值都会被忽略掉