튀김족발
공부 끄적이는 공간
튀김족발
전체 방문자
오늘
어제
  • 분류 전체보기 (33)
    • C++ (10)
    • DirectX (12)
    • Unreal (11)
    • Unity (0)
    • EASTL (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
튀김족발

공부 끄적이는 공간

10. STL tuple
C++

10. STL tuple

2023. 3. 27. 20:29

C++ Stl 중에 튜플이 있다. 사용하는데 편한데 어떻게 만들어져있는지 궁금할정도로 신기하다

 

void main()
{
 	std::tuple<float, int> t;
	std::get<0>(t) = 1.2f;
	std::get<1>(t) = 1;

	printf("%g\r\n", std::get<0>(t));
	printf("%i\r\n", std::get<1>(t));
}

출력

1.2
1

이 튜플을 비슷하게 만들어보자

더보기
template<int...> struct seq{};

template<int max, int... s> 
struct make_seq : make_seq<max - 1, max - 1, s...>
{
};

template<int... s> 
struct make_seq<0, s...>
{
	typedef seq<s...> type;
};

template<int max> 
using MakeSeq = typename make_seq<max>::type;

template<int x, typename Arg>
struct foo_storage
{
	Arg data;
};

template<typename Seq, typename... Args>
struct foo_helper{};

template<int s0, int... s, typename A0, typename... Args>
struct foo_helper<seq<s0, s...>, A0, Args...>
	: foo_storage<s0, A0>
	, foo_helper<seq<s...>, Args...>
	{};

template<typename... Args>
struct foo : foo_helper<MakeSeq<sizeof...(Args)>, Args...>
{
};

template<int N, typename T>
T& get(foo_storage<N, T>& f)
{
	return f.data;
}

위에는 전체 소스이고 하나씩 살펴보자

 

template<int...> 
struct seq{};

template<int max, int... s> 
struct make_seq : make_seq<max - 1, max - 1, s...>
{
};

template<int... s> 
struct make_seq<0, s...>
{
	typedef seq<s...> type;
};

template<int max> 
using MakeSeq = typename make_seq<max>::type;

여기에는 가변길이 템플릿을 사용한다.

make_seq는 어떤 max 값을 주면 그 max 값에 해당하는 int의 seq에 해당하는 type을 정의한다. (내가 적어도 뭔말인지 모르겠다 허헣)

이런 식으로 3을 넣으면 0~2까지의 seq를 정의한다.

따라서

이렇게 결과가 나온다.

 

template<int...>
struct seq{};

int형의 가변길이 템플릿을 받는 seq를 정의한다.

 

이 seq는

template<int... s> 
struct make_seq<0, s...>
{
	typedef seq<s...> type;
};

make_seq의 type을 정의한다.

 

struct make_seq : make_seq<max - 1, max - 1, s...>
{
};

그리고 make_seq는 상속 받는 make_seq보다 1 작은 make_seq를 상속받는다.

그리고 종료조건으로 

template<int... s> 
struct make_seq<0, s...>
{
	typedef seq<s...> type;
};

0일경우 마지막 베이스 클래스를 만든다.

 

헷갈린다.

 

이런 식으로 상속을 받게 된다.

따라서 

MakeSeq<2>의 타입은 seq<0,1>이 된다.

 

template<int x, typename Arg>
struct foo_storage
{
	Arg data;
};

여기서 foo_storage를 보면 int형에 대응하는 타입을 갖고 이 타입을 내부에서 타입에 해당하는 멤버변수 데이터를 선언한다. 각 인티저의 시퀀스마다 타입을 갖는다.

 

template<typename Seq, typename... Args>
struct foo_helper{};

가변길이 템플릿 Args를 갖는다. 그리고 특화버전을 작성한다.

template<int s0, int... s, typename A0, typename... Args>
struct foo_helper<seq<s0, s...>, A0, Args...>
	: foo_storage<s0, A0>
	, foo_helper<seq<s...>, Args...>
	{};


특화버전은 int형의 리스트가 n개 오고, 그리고 타입 리스트가 n개 옵니다. 따라서 int형의 리스트가 n개면 타입도 n개가 와야 한다.
이 작성의 의도는 0,1,2가 연속이 되고, 타입을 float, int, long을 작성 한다면 0을 float 1을 int 2를 long에 대응하도록 구성하려는 의도다.

foo_helper의 특화버전이 seq를 파라미터로 받는다면 

struct foo_helper<seq<s0, s...>

이 seq의 s0부터 n-1까지의 시퀀스가 foo_helper의 int형의 seq에 매핑이 되고,

, A0, Args...>

나머지 타입 인자가 타입에 매핑이 된다.

 

: foo_storage<s0, A0>

그리고 상속받기를 foo_helper의 첫번째 int형의 seq를 foo_storage의 첫번째에 넣고 첫번째 자료형을 첫번째 자료형에 넣는다. 이렇게 하면, 그 seq에 해당하는 데이터를 내부에서 선언하는 base클래스를 갖게 된다.

	, foo_helper<seq<s...>, Args...>
	{};

그 다음에 int형의 시퀀스를 계속 받기 위해 재귀적으로 상속을 받는다.

 

이렇게 하면

foo_helper<seq<0,1>,float,int> 를 선언한다면 이런 구조록 만들어진다.

 

template<typename... Args>
struct foo : foo_helper<MakeSeq<sizeof...(Args)>, Args...>
{
};

여기서 보면 MakeSeq<sizeof...(Args)>, Args...>에서 sizeof...(Args)는 가변길이 템플릿에서 템플릿에서 전달된 타입의 갯수를 구하는 연산자이다. 따라서 Args의 갯수를 의미한다.

위에는 궁극적으로는 MakeSeq에 sizeof에 Args를 전달하여 foo<seq<s0. s...> 부분을 자동적으로 생성하게 된다.

 

template<int N, typename T>
T& get(foo_storage<N, T>& f)
{
	return f.data;
}

마지막으로 위에 그림 구조로 만들어지니까 N과 T를 reference로 넘겨주면 접근 하게 된다.

 

void main()
{
	foo<float, int> t;
	get<0>(t) = 1.2f;
	get<1>(t) = 2;
	printf("%g\r\n", get<0>(t));	
	printf("%i\r\n", get<1>(t));	
}

이제 이것들을 실행시키면

 

출력이 된다....
마참내 std에서 제공하는 튜플과 비슷하게 작동하게 만들었다.

'C++' 카테고리의 다른 글

9. STL Equality and Equivalence  (0) 2023.02.08
8. STL Custom Allocator  (0) 2023.02.07
7. CRTP, Static Plymophism and Rebind  (0) 2023.01.09
6. STL Placement new  (0) 2022.12.17
5. Operator Overloading03 operator new  (2) 2022.12.17
    'C++' 카테고리의 다른 글
    • 9. STL Equality and Equivalence
    • 8. STL Custom Allocator
    • 7. CRTP, Static Plymophism and Rebind
    • 6. STL Placement new
    튀김족발
    튀김족발

    티스토리툴바