C++0x 미리보기 13, Concepts는 다음 기회로(1부)

Twitter icon류광, 2009-08-30 16:08
일정 상의 문제 때문에 C++0x에서 concepts를 빼기로 했답니다.

Concepts라는 것은 템플릿 함수의 인수에 대한 일단의 제약 조건들을 지정하기 위한 메커니즘을 말합니다. 현재의 C++98/03에서는 템플릿 인수에 대한 제약이 없습니다. 예를 들어 보겠습니다.

template<typename T>
void f(T& obj) {
  obj.eat();
  g(obj); 
}

template<typename T>
void g(T& obj) {
 obj.walk();
 h(obj); 
}

template<typename T>
void h(T& obj) { obj.quack(); }

...

struct Platypus // 오리 너구리
{
 void eat();
 void walk(); 
};

...

Platypus donald; // 도널드 덕구리
f(donald);

f(donald);는 유효한 호출이 아닙니다. Platypusquack()이라는 멤버가 없기 때문입니다. 그런데 컴파일러는 f(donald);가 유효한 호출이 아님을 f()g()를 거쳐서 h()의 인스턴스화 시점에 가서야 알 수 있습니다. 이 때문에 컴파일 시간이 늘어나고 컴파일 오류 메시지도 길고 애매모호해집니다.[1]

반면 전통적인 OOP의 상속 기반 메커니즘에서는 이런 문제가 없습니다. void f(Duck& d);이었다면, PlatypusDuck을 상속하지 않으므로 컴파일러는 f(donald); 호출문 자체에 대해 문제점을 지적해 줄 것입니다. 그렇다고 상속 계통구조를 도입하는 것은 코드를 필요 이상으로 경직되고 무겁게 만들 수 있습니다. 전통적인 OOP에 비한 GP(일반적 프로그래밍)의 장점을 여기서 길게 나열할 필요는 없을 것 같습니다. 위의 예제에 암시되어 있는 덕 타이핑(동적 언어만의 특징으로 오해되는)에 대해서는 나중에 따로 글을 한 번 쓰겠습니다.

각설하고, 템플릿의 여러 장점을 포기하지 않으면서도 상속 기반에서처럼 ‘이른 점검’이 가능하다면 좋을 것입니다. 이를 사용자 차원에서 해결하는 것도 아예 불가능하지는 않지만(한 가지 예), 언어 차원에서 지원하는 것보다는 장황하고 번거로울 수밖에 없습니다. Concepts가 바로 그러한 언어 차원의 지원 시도입니다. 다음은 min의 두 인수가 비교가 가능해야 함을 Concepts를 이용해서 명시적으로 표현한 예입니다.

concept LessThanComparable<typename T>
  { bool operator<(T x, T y);}

template<LessThanComparable T>
const T& min(const T& x, const T& y)
    { return x < y? x : y; }

template < ... > 안에 typename이나 class 대신 LessThanComparable이 쓰였음에 주목하세요. 이는 T가 ‘임의의’ 형식이 아니라 LessThanComparable라는 ‘개념(concept)’을 만족하는 형식이어야 함을 뜻합니다. 그리고 LessThanComparable이라는 개념은 T들을 < 연산자로 비교할 수 있어야 함을 요구합니다. 이러한 명시적인 제약 덕분에, 만일 사용자가 operator<가 정의되지 않은 어떤 형식으로 min()을 호출하면 컴파일러는 인수들이 LessThanComparable을 만족하지 못한다는 좀 더 직접적이고 명확한 오류 메시지를 제공할 수 있게 됩니다.

그리고 Concepts가 오류 메시지를 위한 것만은 아닙니다. 라이브러리 구현자라면 Concepts를 통해서 템플릿 함수를 좀 더 세부적으로 중복적재할 수 있다는 점에 주목할 것입니다. 현재의 템플릿 메커니즘에서는, 예를 들어 copy 알고리즘의 인수들이 임의 접근 반복자일 때에는 좀 더 효율적인 버전(원본 구간의 크기를 알아내서 메모리를 미리 할당하는 등)을 제공하고, 최소한의 조건만 만족하는 입력 반복자이면 통상적인 루프를 사용하는 식으로 구현을 최적화하는 것이 불가능하거나 어렵습니다.

그런데 안타깝게도 C++ 표준 위원회는 최근 회합(2009년 7월, 프랑크푸르트)에서 Concepts를 차기 C++ 표준에 포함시키지 않기로 했습니다. 이유는 간단히 말하면 “시간 부족”이지만 길게 이야기하자면 긴데요. 이 글의 제2부에서 좀 더 이야기하겠습니다.

참고로, Concepts 제안의 주요 인물 중 하나인 Doug Gregor가 이와 관련해서 쓴 글을 최흥배님이 번역하셨습니다: 프랑크푸르트에서 어떤 일이 있었는가? - 상, .


  1. 컴파일러들이 점점 똑똑해지면서 오류 메시지의 품질도 계속 좋아지고 있긴 합니다... 

태그: C++ C++0x

comments powered by Disqus

예전 댓글(읽기 전용)