(C++ : Template) 같은 데이터형이라도 포인터인지 아닌지에 따라 다른 template 생성

Posted by : at

Category : Cpp


void foo(int n) {}
void foo(double d) {}

int main()
{
  foo(3);       // foo(int)
  foo(3.4);     // foo(double)
  
  // 아래를 void foo(double d)를 호출하게 할 순 없나?
  foo(0);
  foo(1);
}
template<int N> struct int2type
{
  enum { value = N };
};

void foo(int n) {}

int main()
{
  int2type<0> t0;
  int2type<1> t1;
  // t0와 t1은 다른 타입이 된다.
  /*
  // int2type<0>
  template<0> struct int2type
  {
    enum { value = 0 };
  };
  
  // int2type<1>
  template<1> struct int2type
  {
    enum { value = 1 };
  };
  */
  
  foo(t0);
  foo(t1);
  // 둘은 다른 함수를 부르게 된다. -> 함수오버로딩을 유발할 수 있다.
}

그래서?? 갑자기 무슨말이지?

#include <iostream>
using namespace std;

template<typename T> struct xis_pointer
{
  static constexpr bool value = false;
};

template<typename T> struct xis_pointer<T*>
{
  static constexpr bool value = true;
};

template<typename T> void printv(T v)
{
  if (xis_pointer<T>::value)    // if문은 런타임에 if문을 확인하기에 아래코드를 모두 컴파일하게 된다.
    cout << v << " : " << *v << endl;   // 컴파일 중 여기서 *v 참조를 할 수 없음.
  else
    cout << v << endl;
}

int main()
{
  int n = 3;
  printv(n);  // error
  printv(&n);
}
template<typename T> void printv(T v)
{
  if constexpr (xis_pointer<T>::value)  // C++17에서 이렇게 쓰면 간단하게 해결되긴 한다.
    cout << v << " : " << *v << endl;
  else
    cout << v << endl;
}

// C++17이 아니라면?
// 사용이 되어야지만 아래 코드가 생성됨을 기억하자(지연된 인스턴스)
// 그런데 이렇게 한다 하더라도 ... 결국 컴파일 시간에 아래 코드가 생성되며 에러가 발생..
template<typename T> void printv_pointer(T v)
{
  cout << v << " : " << *v << endl;
}

template<typename T> void printv_not_pointer(T v)
{
  cout << v << endl;
}

template<typename T> void printv(T v)
{
  if (xis_pointer<T>::value)  // 컴파일 타임에 결정할 수 없기에 아래 코드를 생성
    printv_pointer(v);
  else
    printv_not_pointer(v);
}

int main()
{
  int n = 3;
  printv(n);
  printv(&n);
}
template<typename T> void printv_imp(T v, int2type<1>)
{
  cout << v << " : " << *v << endl;
}

template<typename T> void printv_imp(T v, int2type<0>)
{
  cout << v << endl;
}

template<typename T> void printv(T v)
{
  printv_imp(v, int2type<xis_pointer<T>::value>());
  // int2type<1>() = 새로운 타입
}

int main()
{
  int n = 3;
  printv(n);
  printv(&n);
}

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links