7.4 成员函数模板¶
普通类的成员模板¶
我们定义一个类,类似unique_ptr使用的默认删除器类型,我们的类将包含一个重载的函数调用运算符,它接受一个指针并对此指针执行delete。与默认删除器不同,我们的类还将在删除器被执行时打印一条信息。由于希望删除器适用于任何类型,所以我们将调用运算符定义为一个模板:
#include <iostream>
#include <memory>
// 函数对象类, 对给定指针执行delete
class DebugDelete {
public:
explicit DebugDelete(std::ostream &s = std::cerr) : os_(s) { }
template <typename T> void operator()(T *p) const {
os_ << "deleting unique_ptr" << std::endl;
delete p;
}
private:
std::ostream &os_;
};
int main() {
// 在一个临时对象上调用operator()(int*)
double *pd = new double;
DebugDelete()(pd);
// 将DebugDelete用作unique_ptr的删除器
// 实例化DebugDelete::operator()<int>(int*)
std::unique_ptr<int, DebugDelete>p(new int, DebugDelete());
return 0;
}
类模板的成员模板¶
对于类模板,我们也可以为其定义成员模板。在此情况下,类和成员各自有各自的、独立的模板参数。
#include <iostream>
#include <memory>
#include <vector>
#include <list>
#include <string>
// 定义Foo的构造函数, 接受两个迭代器表示要拷贝的元素范围
template <typename T> class Foo {
public:
template <typename It> Foo(It b, It e);
private:
std::shared_ptr<std::vector<T>> data_;
};
template <typename T>
template <typename It>
Foo<T>::Foo(It b, It e) : data_(std::make_shared<std::vector<T>>(b, e)) { }
int main() {
// 实例化Foo<int>类的接受两个int*参数的构造函数
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Foo<int> f1(std::begin(ia), std::end(ia));
// 实例化Foo<int>类的接受两个vector<long>::iterator参数的构造函数
std::vector<int64_t> vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Foo<int> f2(vi.begin(), vi.end());
// 实例化Foo<string>类的接受两个list<const char*>::iterator参数的构造函数
std::list<const char*> w = {"tomo", "cat", "tomocat"};
Foo<std::string> f3(w.begin(), w.end());
}