模板具現化型別之間無隱式轉換關係(SmartPtr<Derived> 不能隱式轉 SmartPtr<Base>),需自行提供轉換建構函式。
template<typename T>
class SmartPtr {
public:
SmartPtr() = default;
template<typename U>
SmartPtr(const SmartPtr<U>& other) : heldPtr(other.get()) {
cout << "SmartPtr:CopyConstructor" << endl;
}
T* get() const { return heldPtr; }
private:
T* heldPtr;
};
僅允許 Derived* 隱式轉 Base*,利用 other.get() 隱式轉換在成員初始化列表中由編譯器檢查。若 U* 不可轉 T*,編譯失敗。
/* test.cpp
* Created on: 2014.04.20
* Author: Spike
*/
#include <iostream>
using namespace std;
class Base{};
class Derived : public Base {};
template<typename T> class SmartPtr {
public:
SmartPtr() = default;
template<typename U>
SmartPtr(const SmartPtr<U>& other) : heldPtr(other.get()) {
cout << "SmartPtr:CopyConstructor" << endl;
}
T* get() const { return heldPtr; }
private:
T* heldPtr;
};
int main() {
SmartPtr<Derived> spd;
SmartPtr<Base> spb(spd); // OK:Derived* -> Base*
// SmartPtr<Derived> spd2(spb); // 錯誤:Base* 不能轉 Derived*
SmartPtr<Base> spb2;
SmartPtr<Base> spb3(spb2); // 同型別,使用預設複製建構
return 0;
}
SmartPtr:CopyConstructor
std::enable_if 或 C++20 Concepts 可更精確限制轉換條件。