template<class T> class SmartPtr
{
	T* ptr = nullptr;
public:
	SmartPtr() = default;
	SmartPtr(T* p) : ptr(p) {}

	// template 생성자.
	template<class U,
					 class = std::enable_if_t<std::isconvertible_v<U*, T*>>> // 변환이 가능할때만 사용.
	SmartPtr(const SmartPtr<U>& sp) : ptr(sp.ptr) {}

	// 다른 타입의(Dog, Animal) private에 접근하는것을 허용하기 위해 등록.
	// SmartPtr이 템플릿이고, 그것이 friend라는것을 써준것.
	template<class> friend class SmartPtr;
};

int main()
{
	SmartPtr<Dog> sp1(new Dog);
	SmartPtr<Animal> sp2 = sp1;
}