본문 바로가기
프로그래밍/C++

이상하게 반복되는 템플릿 패턴(Curiously Recurring Template Pattern, CRTP)

by bantomak 2023. 9. 25.

이상하게 반복되는 템플릿 패턴

CRTP(Curiously Recurring Template Pattern)는 클래스 x가 x 자체를 사용하는 클래스 템플릿 인스턴스화에서 파생되는 C++의 관용어이다. 이를 통해 가상 함수 없이도 동일한 함수를 여러 클래스에서 사용할 수 있는 정적 다형성을 구현할 수 있다. 하지만 이 패턴을 사용하는데는 몇 가지 문제가 있는데 주요 문제 중 하나는 메서드 숨김으로, 파생 클래스가 부모 클래스의 메서드를 실수로 숨실 수 있다는 것이다. (동일한 메서드명으로 선언) 추가로 CRTP 기본 클래스가 템플릿이어야 하므로 복잡성이 증가되고 디버깅하기 어려운 오류가 발생할 수 있다는 것이다.

 

메서드 숨김 문제를 해결하려면 베이스 클래스에서 메서드를 선언할 때 가상 키워드(virtual)를 사용하는 것이 좋다. 이렇게 하면 모든 파생 클래스가 기본 클래스의 메서드를 상속하게 된다. CRTP를 방문자 패턴과 결합하여 객체의 유형에 따라 다른 동작을 구현할 수 있다.

 

예제

이상하게 반복되는 템플릿 패턴은 클래스 X가 클래스 템플릿 Y에서 파생되는 관용어로, 템플릿 매개변수 Z를 취하며, 여기서는 Y는 Z = X로 인스턴트화 된다. 예를 들어

template<class Z>
class Y {};
 
class X : public Y<X> {};

 

기본 클래스가 인터페이스를 노출하고 파생 클래스가 해당 인터페이스를 구현하는 '컴파일 타임 다형성(Compile-time Polymorphism)'을 구현하는데 CRTP를 사용할 수 있다.

 

#include <iostream>
 
template <class Derived>
struct Base { void name() { (static_cast<Derived*>(this))->impl(); } };
 
struct D1 : public Base<D1> { void impl() { std::cout << "D1::impl()\n"; } };
struct D2 : public Base<D2> { void impl() { std::cout << "D2::impl()\n"; } };
 
int main()
{
    Base<D1> b1; b1.name();
    Base<D2> b2; b2.name();
 
    D1 d1; d1.name();
    D2 d2; d2.name();
}

Output :

D1::impl()
D2::impl()
D1::impl()
D2::impl()

 

참고 사이트

 

C++ - 흥미롭게 반복되는 템플릿 패턴 - CRTP(Curiously Recurring Template Pattern)는 클래스 X가 X 자체를 사

CRTP(Curiously Recurring Template Pattern)는 클래스 X가 X 자체를 사용하는 클래스 템플릿 인스턴스화에서 파생되는 C++의 관용어입니다.이를 통해 가상 함수 없이도 동일한 코드를 여러 클래스에서 사용

runebook.dev

'프로그래밍 > C++' 카테고리의 다른 글

htons(), htonl() 함수에 대해서  (8) 2023.08.14
C++ MAKEWORD에 대해서  (2) 2023.08.14

댓글