Posted on 2008-11-03 20:36
Batiliu 閱讀(481)
評論(0) 編輯 收藏 引用 所屬分類:
讀書筆記
第一條 vector的使用
設計vector是用來代替內置數組的,因此其效率應該與內置數組一樣,內置數組在下標索引(operator[])時是不進行越界檢查的。如果你需要下標越界檢查,可以使用at方法。
- size告訴你容器中目前實際有多少個元素,而對應地,resize則會在容器的尾部添加或刪除一些元素。這兩個函數對list、vector、deque都適用,但對其他容器并不適用。
- capacity則告訴你最少添加多少個元素才會導致容器重分配內存,而reserve在必要的時候總是會使容器的內部緩沖區擴充至一個更大的容量,以確保至少能滿足你所指出的空間大小。這兩個函數僅對vector適用。
第二條 第三條 字符串格式化
|
sprintf snprintf stringstream strstream boost::lexical_cast |
易用嗎,代碼清晰明確嗎 高效嗎,無額外內存分配嗎 長度安全嗎 類型安全嗎 是否可以用于模板之中 |
是 是 否 否 是 是 是 否 是 否 否 是 是 是 是 否 否 是 是 是 否 否 是 是 是 |
第四條 標準庫成員函數
使用標準庫里面的mem_fun,將成員函數適配為仿函數(functor),從而可被標準庫算法以及其他正常情況下只適用自由函數的代碼所使用。但不要將它用在標準庫自己身上。
第五條 第六條 泛型性的風味
// 示例:重載swap()。
class X {
public:
void swap(X&);
};
// 注意:這個重載并沒有放在std名字空間當中。請參考名字空間Koenig查找。
swap(X&a, X&b) {
a.swap(b);
}
第七條 泛型性的風味
在如下代碼中,最后一行代碼調用的是f()的那個版本?
// 示例:函數特化。
template <typename T> // (a):一個主模板
void f(T);
template <typename T> // (b):一個主模板,重載了(a)
void f(T*);
template <> // (c):(a)的一個顯示特化(全特化)
void f<int*>(int*);
template <> // (d):(b)的一個顯示特化(全特化)
void f<int>(int*);
// ....
int * p;
f(p); // 調用的哪個版本?
答案是……調用(d),想必結果是你意料之中。如果我們注釋掉(d),f()調用的又是哪個版本呢?答案是……調用(b),是不是讓你大吃一驚?如果這令你感到驚訝的話,你并不是唯一一個,當時它曾讓許多專家大吃一驚。理解這個例子的關鍵其實很簡單:模板特化并不參加重載。
讓我們來看看函數模板的重載規則。
- 非模板函數是C++中的一等公民。如果一個普通的非模板函數跟一個函數模板在重載解析的參數匹配中表現一樣好的話,編譯器會選擇普通函數。
- 如果編譯器沒有發現合適的一等公民,那么主函數模板作為C++中的二等公民就會被納入考慮。具體選擇哪個主函數模板則取決于哪個的參數類型匹配的最好。
- 如果這個被選中的主函數模板碰巧有針對所使用的模板實參做了特化的話,該特化版本才會被編譯器選中。否則編譯器將使用以正確類型實例化的主模板。
- 等等
// 示例:函數特化。
template <typename T>
struct X;
template <typename T> // 請不要動這個函數
void f(T t) { X<T>::far(t); }
template <typename T> // 可以對這個函數進行特化
struct X {
static void f(T t);
};
第八條 友元模板
// 示例:友元模板。
namespace boost {
template <typename T> void checked_delete(T* x);
}
class Test {
friend void boost::checked_delete<Test>(Test* x); // 或"checked_delete<>(Test* x)"
}
第九條 第十條 導出限制
第十一條 第十二條 異常安全問題