«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
04-25 21:10
관리 메뉴

lancelot.com

coercion by member template 본문

프로그래밍

coercion by member template

lancelot50 2022. 7. 30. 17:31
  • Dog 포인터가 Animal의 포인터에 대입가능하면, smartptr<Dog> 의 포인터도 smartptr<Animal> 의 포인터에 대입가능해야한다.
    • template 생성자 필요
    • template class smartptr 을 friend 로 선언 필요 (생성자에서 private member에 접근해야하므로)
class Animal {};
class Dog : public Animal {};

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

//	smartptr(const smartptr<T>& sp) {}		// 같은 타입만 받을 수 있다.
//	smartptr(const smartptr<Dog>& sp) {}	// smartptr<Dog>만 받을 수있다.

	// template 생성자
	template<typename U>
	smartptr(const smartptr<U>& sp) : ptr(sp.ptr) { }

	template<typename U> friend class smartptr;
};

int main()
{
	Dog* p1= new Dog;
	Animal* p2 = p1;

	smartptr<Dog> sp1(new Dog);
	smartptr<Animal> sp2 = sp1;
}

 

  • enable_if 를 사용하면, 오류상황에서 조금 더 명확하게 메세지를 전달할 수 있다.
#include<type_traits>

class Animal {};
class Dog : public Animal {};

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

//	smartptr(const smartptr<T>& sp) {}		// 같은 타입만 받을 수 있다.
//	smartptr(const smartptr<Dog>& sp) {}	// smartptr<Dog>만 받을 수있다.

	// template 생성자
	template<typename U, typename=std::enable_if_t<std::is_convertible_v<U*, T*>> > // 포인터 타입이 변환 가능한지를 체크
	smartptr(const smartptr<U>& sp) : ptr(sp.ptr) { }

	template<typename U> friend class smartptr;
};

int main()
{
	Dog* p1= new Dog;
	Animal* p2 = p1;

	smartptr<Dog> sp1(new Dog);
	smartptr<Animal> sp2 = sp1;

	smartptr<int> sp3(new int);
	smartptr<double> sp4 = sp3;	// enable_if 를 사용해서, error 메세지를 좀 더 명확하게 함
}