成員模板可存在於普通類別或類模板中。普通類別中使用時自動推導模板實參;類模板中成員函數模板參數可與類別參數不同,定義時需提供兩組模板參數列表(第一組為類別的,第二組為成員的)。
/*
* cppprimer.cpp - 成員函數模板範例
* Created on: 2013.11.24
* Author: Caroline
* eclipse cdt, gcc 4.8.1
*/
#include <iostream>
#include <functional>
#include <memory>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <iterator>
// 函數模板預設參數
template <typename T, typename F = std::less<T>>
int compare(const T &v1, const T &v2, F f = F()) {
if (f(v1, v2)) return -1;
if (f(v2, v1)) return 1;
return 0;
}
// 成員模板範例:自定義刪除器
class DebugDelete {
public:
DebugDelete(std::ostream &s = std::cerr) : os(s) {}
// 成員函數模板:自動推導 T
template <typename T>
void operator()(T *p) const {
os << "deleting unique_ptr" << std::endl;
delete p;
}
private:
std::ostream &os;
};
// 類模板中的成員模板建構子
template <typename T>
class Blob {
public:
template <typename It>
Blob(It b, It e); // 宣告
// 定義需雙重模板參數
template <typename It>
Blob(It b, It e) {
std::sort(b, e); // 需支援排序的迭代器
}
};
int main(void) {
std::cout << "compare(0, 42) = " << compare(0, 42) << std::endl;
double* p = new double;
DebugDelete d;
d(p); // 自動推導 T 為 double
DebugDelete()(new int); // 臨時物件呼叫
// 搭配 unique_ptr 使用自定義刪除器
std::unique_ptr<int, DebugDelete> pi(new int, DebugDelete());
std::unique_ptr<std::string, DebugDelete> ps(new std::string, DebugDelete());
// 成員模板建構子接受各種迭代器
int ia[] = {9, 8, 7, 6, 5};
std::vector<long> vi = {5, 4, 3, 2, 1, 0};
std::deque<std::string> w = {"lady", "girl", "woman", "now"};
Blob<int> a1(std::begin(ia), std::end(ia));
Blob<int> a2(vi.begin(), vi.end());
Blob<std::string> a3(w.begin(), w.end());
// 驗證排序結果
std::cout << "int ia[] = ";
for (const auto i : ia) std::cout << i << " ";
std::cout << std::endl; // 輸出: 5 6 7 8 9
return 0;
}
std::sort 的迭代器型別DebugDelete 展示函數物件作為刪除策略