template<class Outer>
struct S1 {
template<class Inner>
S1(const S1<Outer>& rhs) {}
};
template<class Outer>
struct S2 {
template<class Inner>
S2(const S2<Inner>& rhs) {}
};
S1<float> s1f;
S2<float> s2f;
S1<double> s1d(s1f); // error
S2<double> s2d(s2f); // ok
演示的是从参数的模板类型中推导出成员函数模板参数。
对于上面的s2d,我们知道Outer是double,指定不推导。
但是,当我们将s2f 传递给它的构造函数时,我们传递的是一个 S2 类型的对象。我们提供了一个接受S2<? Inner ?> 的构造函数,因此如果我们将Inner 推断为float,我们就有一个容器匹配。
演示的是一个带有更多模板化成员函数的模板化类。考虑:
template<class Outer>
struct S {
template<class Other>
S(const Other& rhs) {}
};
如果我们这样做
S<float> sf;
S<int> si(sf);
这里复制构造函数推导出Inner 不仅仅是int 而是S<int>。
实际使用:
template<class C, class T>
struct PtrContainer {
using container_type = C;
using value_type = T;
using self_type = PtrContainer<container_type, value_type>;
using ptr_type = T*;
using size = sizeof(T);
PtrContainer() : c() {}
void append(ptr_type p) {
c.push_back(p);
}
template<class D>
std::enable_if<std::is_base_of<T, D>::value, void>::type
transfer(PtrContainer<D>& rhs) {
c.insert(c.end(), rhs.c.begin(), rhs.c.end());
rhs.c.clear();
}
void clear() {
for (auto* ptr: c) {
delete ptr;
}
c.clear();
}
~PtrContainer() { clear(); }
container_type<ptr_type> c;
};
struct S {};
struct SD : public S {};
int main() {
PtrContainer<vector, S> pvs;
pvs.append(new S);
PtrContainer<list, SD> plsd;
plsd.append(new SD);
pcs.transfer(plsd);
}