条款45:运用成员函数模板接收所有兼容类型
Use member function templates to accept "all compatible types".
class Top { ... };
class Middle: public Top { ... };
template<typename T>
class SmartPtr {
public:
explicit SmartPtr(T* realPtr);
...
};
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle); // 无法通过编译
同一个 template 的不同具现体(instantiations)之间并不存在固有关系,所以编译器会视 SmartPtr<Middle>
和 SmartPtr<Top>
为完全不同的两个类。
member function templates
通过 member function templates 可以实现 templates 之间的自动转型:
template<typename T>
class SmartPtr {
public:
template<typename U>
Smart(const SmartPtr<U>& other);
};
但在实际应用中,我们希望根据一个 SmartPtr<Bottom>
创建一个 SmartPtr<Top>
,却不希望通过SmartPtr<Top>
创建一个 SmartPtr<Bottom>
。所以可以使用成员初值列(member initialization list)来初始化 SmartPtr<T>
之类型为 T*
的成员变量,从而增加一条限定条件,即“存在某个隐式转换可以将一个 U*
指针转为一个 T*
指针”时,编译才可通过:
template<typename T>
class SmartPtr {
public:
template<typename U>
SmartPtr(const SmartPtr<U>& other): heldPtr(other.get()) { ... }
T* get() const { return heldPtr; }
private:
T* heldPtr;
};
Last updated
Was this helpful?