C++ Local Class as Template Argument
이 글은 최철호 군의 local function object를 stl algorithm function들에 사용하지 못하는 이유에 대한 답변입니다.
한마디로 말하면, 로컬 클래스(local class)는 템플릿 인자로 사용될 수 없기 때문입니다.
local function object는 로컬 클래스이고, for_each는 functor (function object)의 타입을 템플릿 인자로 받는 템플릿 함수입니다. 함수 인자로부터 템플릿 인자가 deduce되기 때문에 템플릿 인자가 생략되어 일반 함수처럼 보이는 것 뿐이죠.
템플릿 인자는 linkage를 필요로 합니다. 특정 템플릿 인자에 대한 템플릿의 인스턴스는 서로 다른 컴파일 유닛에서 사용되므로 특정 컴파일 유닛에 속한다고 할 수가 없을거라는 걸 생각하면 당연히 그럴테죠. (컴파일 과정에서 생성된 템플릿 인스턴스는 다른 소스 파일에 존재한다고 생각하시면 편합니다.)
한편, 로컬 클래스는 linkage가 없습니다. (C++ Standard의 [basic.link] 부분을 참조하세요.) 정확한 이유는 모르겠으나, linkage를 가지게 되는 순간부터 문법과 구현 모두 복잡해지기 시작할 것임을 쉽게 상상할 수 있습니다.
gcc 4.1를 사용한 컴파일에서는 ‘no matching function for call to …’와 같은 오류를 발생합니다. 이러한 오류가 발생한 이유는 이해할 수 있으나, 약간이라도 가능성이 있는 경우들을 잘 보여주지 않는 불친절한 gcc 컴파일 오류의 사례를 보여주고 있네요.
로컬 클래스의 인스턴스를 로컬 스코프에서 사용한 이런 자연스러운 경우를 표현하지 못하는 것은 좀 아쉽습니다. C++의 algorithm과 functional은 C++에서 빼놓을 수 없는 요소일 뿐만 아니라 그 사용이 상당히 권장되고 있습니다. 이 때 사용되는 functor들을 일일이 namespace 스코프에 정의해서 namespace에 난립하게 하는 것도 그다지 바람직하지 않은 것 같구요. 로컬 클래스는 오히려 functor와 같은 크기도 작고 용도도 한정적인 경우에 가장 유용하겠죠. 그래서인지 Anthony Williams에 의해 로컬 클래스에 linkage를 부여하자는 제안 (Making Local Classes more Useful)도 나와있네요.