arr = [1, 3.14, 0x16]
위의 파이썬 코드는 아무 문제 없시 사용이 가능합니다
하지만 이를 C++에서 구현을 하려면 어떻게 해야할까요?
이를 C++에서 구현하기 위해서는 '가변 길이 템플릿', '후행 리턴 타입', 'common_type'에 대한 개념이 필요합니다
먼저 가변 길이 템플릿부터 알아보도록 하겠습니다.
가변 길이 템플릿
이란 <typename T, typename... Types> 의 두번째 템플릿 매개변수 typename뒤에오는 '...' 를 의미합니다.
이를 템플릿 파라미터 팩이라고 부릅니다.
print(1, 3.14, 0x16)
파이썬에서 print함수는 처럼 막 바로 출력이 가능합니다.
이를 C++로 구현을 하면은
template <typename T>
void Print(T arg)
{
std::cout << arg << std::endl;
}
template <typename T, typename... Types>
void Print(T arg, Types... args)
{
std::cout << arg << ", ";
Print(args...);
}
위처럼 구현할 수 있습니다.
템플릿 메타 프로그래밍으로 factorial을 구현할때
template <int N>
struct Fac
{
static const int value = N * Fac<N - 1>::value;
};
template <>
struct Fac<1>
{
static const int value = 1;
};
int main()
{
std::cout << Fac<5>::value << std::endl;
return 0;
}
위처럼 구현할 수 있는데요 탈출조건으로 Fac<1>를 '템플릿 특수화'를 통해 구현한 것처럼
첫번째 Print함수를 통해 탈출 조건을 넣어 준 것입니다.
컴파일러는 컴파일 타임에 Print의 첫번째 버전, 두번째 버전 중에 선택을 해야하는데
Print(1, 3.14f, "Hello");을 호출하는 경우 첫번째 버전은 패스하고 두번째 버젼으로 선택됩니다.
이때 T는 1 int타입으로 추론되고 args...는 float, const char*로 추론됩니다.
이후 Print를 재귀적으로 다시 호출하기 때문에
그다음의 T는 float, args는 const char* 로 추론이 되며 마지막에 첫번째 Print로 T가 const char*로 결정이 됩니다.
common_type
type traits는 TR1에서 에서 처음도입 되었고 C++11에서 확정되었습니다.
데이터 타입에 의존하는 동적을 정의하는 메커니즘을 제공합니다.
위의 type_traits에 정의되어 있는 common_type은 두 개 이상의 타입으로 부터 'common type'을 처리할 수 있게 해줍니다.
쉽게 말하면 std::common_type은 C++ 표준 라이브러리에 포함된 템플릿 구조체로, 두 가지 이상의 자료형이 있을 때 이들 자료형들이 함께 작동할 수 있는 공통된 자료형을 찾는 것을 도와줍니다. 쉽게 말해서, 다양한 자료형을 합치는 방법이 어떤 자료형이 되어야 하는지 알려주는 것입니다.
후행 리턴 타입
'auto' : 값에 상응하는 형식을 '컴파일 타임'에 추론해주는 키워드입니다.
'trailing return type(후행 리턴 타입)'은 auto 키워드로 정의된 함수의 반환형식을 명시적으로 알려주는 역할을 합니다.
후행 리턴 타입이 무엇인지는 코드를 보면서 바로 설명을 드리도록 하겠습니다.
구현
위의 세가지 개념을 통해서 파이썬 리스트와 유사한 동작을 수행할 수 있는 정적 배열을 구현해보도록 하겠습니다.
template <typename ... Args>
auto build_array(Args&&... args) ->
std::array<typename std::common_type<Args...>::type, sizeof...(args)>
{
using commonType = typename std::common_type<Args...>::type;
// 배열 생성
return { std::forward<commonType>((Args&&)args)... };
}
먼저 정적 배열의 크기를 어떻게 받아야 할지 모르기때문에 가변길이 템플릿으로 템플릿 매개 변수를 받아주도록 해주고,
타입이 무엇으로 결정될지 모르기 때문에 common_type으로 std::array의 첫번째 템플릿 매개 변수 타입을 결정하고
auto 반환 타입을 '->' 로 std::array<?, ?>라는 후행 리턴 타입으로 auto키워드에 대한 반환 타입을 명시적으로 해줄 수 있습니다.
감사합니다 :)
참고한 자료
가변 길이 템플릿 : https://modoocode.com/294
type_traits : https://junstar92.tistory.com/457
std::forward : https://ansohxxn.github.io/cpp/chapter19-7/
'CPP' 카테고리의 다른 글
[C++] union (DX Matrix) (0) | 2023.09.04 |
---|---|
[C++] initializer_list (0) | 2023.08.23 |
[C++] boost 라이브러리 설치 방법 (0) | 2023.08.17 |
[C++] constexpr (0) | 2023.08.17 |
[C++] 헤더파일의 의미와 Build Process (0) | 2023.08.10 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!