KoreanFoodie's Study

Effective C++ | 항목 41 : 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터 본문

Tutorials/C++ : Advanced

Effective C++ | 항목 41 : 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터

GoldGiver 2022. 10. 25. 16:30

C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!

항목 41 : 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터

핵심 :

1. 클래스 및 템플릿은 모두 인터페이스와 다형성을 지원한다.
2. 클래스의 경우, 인터페이스는 명시적이며 함수의 시그니처를 중심으로 구성되어있다. 다형성은 프로그램 실행 중에 가상 함수를 통해 나타난다.
3. 템플릿 매개변수의 경우, 인터페이스는 암시적이며 유효 표현식에 기반을 두어 구성된다. 다형성은 컴파일 중에 템플릿 인스턴스화와 함수 오버로딩 모호성 해결을 통해 나타난다.


객체 지향 프로그래밍의 세계를 회전시키는 축은 명시적 인터페이스(explicit interface)  런타임 다형성(runtime polymorphism) 이다. 예시를 보자.

class Widget
{
public:
	virtual int normalize();
	void swap(Widdget& other);
};

void doProcessing(Widget& w)
{
	Widget temp(w);
	int a = temp.normalize();
	temp.swap(w);
}

doProcessing 함수를 보자. w 는 Widget 타입이므로, w 는 Widget 인터페이스를 지원해야 한다. 이 인터페이스는 소스 코드에서 어떤 형태인지 확인가능하므로, 이런 인터페이스를 명시적 인터페이스라고 한다.
Widget 의 멤버 함수 중 어떤 것은 가상 함수 이므로, 이 가상 함수에 대한 호출은 런타임 다형성에 의해 이루어진다(런타임에 w 의 동적 타입을 기반으로 결정됨).

템플릿은 암시적 인터페이스(implicit interface)  컴파일 타임 다형성(compile-time polymorphism) 이 중요하다. doProcessing 함수를 템플릿으로 바꿔보자.

template<typename T>
void doProcessing(T& w)
{
	T temp(w);
	int a = temp.normalize();
	temp.swap(w);	
}

w 가 지원해야 하는 인터페이스는 w 에 대해 실행되는 연산이 결정한다. 즉 이 템플릿이 제대로 컴파일 되려면 T 는 복사 생성자, normalize, swap 을 지원해야 한다. 이 표현식들이 바로 T 가 지원해야 하는 암시적 인터페이스이다. 이때, 타입이 '정확히' 일치할 필요는 없다. 즉, normalize 함수가 int 가 아닌 float 을 반환하더라도, 암시적으로 int 로의 형 변환이 가능하므로 인스턴스화가 가능하다는 것이다.
위에서 함수들의 호출을 성공시키기 위해 템플릿의 인스턴스화가 일어나는데(컴파일 도중에 진행됨), 어떤 템플릿 매개변수가 들어가느냐에 따라 호출되는 함수가 달라지기 때문에, 이를 컴파일 타임 다형성이라고 한다.

Comments