More C++ Idioms-43. Int-To-Type

old_dorim·2022년 7월 9일
1

More C++ Idioms

목록 보기
3/4

More C++ Idioms

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms

Idioms라는 용어가 생소하다. 한국어로 하면 관용구인데, 개발 용어로는 그냥 관용구라고 생각하면 안될 것 같아서 서문을 살짝 읽어봤다.

Idiom라는 것은 C++를 사용하여 프로그래밍하거나 설계할 때 자주 사용하게 되는, 재사용 가능한 패턴이나 팁이다. 특정 상황에서 쓰이는, 특정 상황에 대처하기 위한 일반적인 관행이라는 뜻이다.

이 목록은 이런 관용구들을 모아둔 리스트이다. 이 관용구들을 이해함으로써 다른 사람의 코드가 왜 그렇게 짜였는지 읽기 쉬워지고, 언어가 어떤 특성을 가져서 어떻게 짜면 좋은지 등등을 이해할 수가 있다.

이 목록들은 각각 Idiom의 Intent, Also Known As(Alias), Motivation, Solution and Sample Code, Known Uses, Related Idioms, References를 설명한다. 양식이 그렇게 되어있다. 나도 맞춰서 정리하겠다.

동아리 세미나 과제인데, 빨갛게 안 만들어진 페이지빼고 공부한다.

43. Int-To-Type(Integral constant wrappers)

Intent 목적

정수형 상수를 컴파일 타임에 타입으로 취급되게 한다.
정수형 상수 값에 따라 static call dispatch를 구현한다.

dispatch

디스패치란 프로그램이 어떤 메소드를 호출할 것인가를 결정하고 실행하는 것이다. 특히 많은 객체 지향 언어들이 메소드와 프로퍼티들을 오버라이드 할 수 있도록 허용한다. 그러면 받는 인자에 따라 어떤 메소드가 호출될지 여부가 결정이 된다.

Static Dispatch:변수의 명목상 타입에 맞춰서 메소드와 프로퍼티를 참조한다. 이 경우 참조될 요소를 컴파일 타임에 결정된다.
Dynamic Dispatch:변수의 실제 타입의 맞춰서 메소드와 프로퍼티를 호출한다. 코드상으로는 이것이 드러나지 않기 때문에 실제 참조될 요소는 런타임에 결정된다.

참고: https://jcsoohwancho.github.io/2019-10-11-Dynamic-Dispatch%EC%99%80-%EC%84%B1%EB%8A%A5-%EC%B5%9C%EC%A0%81%ED%99%94/

Motivation 동기

C++의 함수 오버로딩은 타입에 의존하기 때문에 정수형 상수가 컴파일 타임에 오버로드 함수가 결정되는 것을 방해한다.
이것을 해결하는 첫번째 방법은 enable-if idiom, 그리고 다른 것이 우리가 설명할 int-to-type idiom이다.

Solution and Sample Code 솔루션과 예제코드

Andrei Alexandrescu가 쓴 Dr. Dobb's Journal에 따르면 해답으로 간단하게 이런 코드를 제공한다.

template <int I>
struct Int2Type
{
  enum { value = I };
};

위의 양식으로 다른 정수는 다른 타입을 가지게 된다. 예를 들어, Int2Type<5>은 Int2Type<10>과 다른 타입이 된다.
또한 정수 파라미터가 관련된 상수 값에 저장이 된다. 이렇게 모든 정수형 상수 결과가 다른 타입이되고, 이 간단한 탬플릿으로 아래 예시처럼 정수형 상수를 통해 static dispatching을 할 수가 있다.

표준 배열 클래스인 TR1과 유사하게, 배열의 고정된 사이즈를 캡슐화하는 배열 클래스가 있다고 가정하자. 사실은 우리의 배열 클래스는 TR1 표준 배열 클래스를 상속하여 구현했으며, 다른 것은 오직 정렬 기능이다.

우리의 정렬 기능은 array의 size를 사용하여 성능을 최적화하고 complie time에 dispatch 작동되도록 의도했다. size를 써서 성능을 최적화한다는 게, 사이즈가 0이면 작동을 막고, 50보다 크기가 작으면 삽입정렬, 더 크면 퀵소트를 쓰게 되어있다. 근데 이러면 어떤 정렬 알고리즘을 쓸지 결정하는게 런타임에 결정될 수 밖에 없다.

이런 경우에 int-to-type idiom을 써서 complie time에 결정되도록 하겠다는 것이다. 아래가 그 예시이다.

#include <iostream>
#include <array>

template <int I>
struct Int2Type
{
  enum { value = I };
};

template <class T, unsigned int N>
class Array : public std::array <T, N>
{
   enum AlgoType { NOOP, INSERTION_SORT, QUICK_SORT };
   static const int algo = (N==0) ? NOOP : 
                           (N==1) ? NOOP :
			   (N<50) ? INSERTION_SORT : QUICK_SORT;
   void sort (Int2Type<NOOP>) { std::cout << "NOOP\n"; }
   void sort (Int2Type<INSERTION_SORT>) { std::cout << "INSERTION_SORT\n"; }
   void sort (Int2Type<QUICK_SORT>) { std::cout << "QUICK_SORT\n"; }
 public:
   void sort()
   {
     sort (Int2Type<algo>());
   }
};
int main(void)
{
  Array<int, 1> a;
  a.sort(); // No-op!
  Array<int, 400> b;
  b.sort(); // Quick sort  
}

몇 개 더 있는 관련된 타입과 상수들이 Int2Type 양식에 의해 정의되어 사용성을 높일 수 있다. 예를 들어 enumeration 값을 정수 상수와 관련된 타입을 회수 하는데 쓸 수 있다.

Finally, other typedefs such as, next and previous are used to find other types in order such that Int2Type<7>::next is the same type as Int2Type<9>::previous.

template <int I>
struct Int2Type
{
  enum { value = I };
  typedef int value_type;
  typedef Int2Type<I> type;
  typedef Int2Type<I+1> next;
  typedef Int2Type<I-1> previous;
};

Known Uses 알려진 사용처

Integral Constant(boost library)
Dimensional Analysis(boost library)
std::integral_constant

enable-if
Type Generator

References 출처

Generic<Programming>: Mappings between Types and Values
https://www.ddj.com/genericprogramming-mappings-between-type/184403750

profile
미래엔 햄스터를 다운 받을 수 있겠지? 설치류니까...

0개의 댓글

관련 채용 정보