Question
오늘 내용은 다시 뉴스그룹에서 하나 가지고 왔습니다. ((comp.lang.c++.moderated:template parameter's namespace exposed?))namespace N {
class A {
};
template <class T>
T1 operator + (T1 op1, T2 op2) { return op1; }
}
}
template <class T>
class B {
};
int main() {
N::A a1, a2;
a1 + a2; // works as it should
B<N::A> b1, b2;
b1 + b2; // oops, this one compiles too!
B<int> b3, b4;
b3 + b4; // no match for operator +, just the way it should be
}
여기서 질문은?- 왜 두번째의 b1 + b2 가 컴파일이 정상적으로 되는가?
- B 클래스가 있는 전역 영역에는 operator + 가 없는데...
Answer
일단 문제를 파악하기 위해서는 ADL ((Argument Dependent Lookup 또는 Argument Dependent Name Lookup. 초기에는 규칙을 만든 사람의 이름을 따서 Koenig Lookup이라고 불렸었습니다.)) 에 대해서 알고 있어야 합니다. 자세한 내용은 Name Lookup이라는 글을 참고하시고요.그럼 이제 찾아봐야 할 내용은 template parameter도 ADL의 규칙에 포함되는가 여부인데요 C++98에 보면 3.4.2.2절의 마지막 부분에 다음과 같은 내용이 있습니다.
--- If T is a template id, its associated namespaces and classes are the namespace in which the template is defined; for member templates, the member template’s class; the namespaces and classes associated with the types of the template arguments provided for template type parameters (excluding template template parameters); the namespaces in which any template template arguments are defined; and the classes in which any member templates used as template template arguments are defined. [Note: nontype template arguments do not contribute to the set of associated namespaces. ]이제 왜 두번째의 b1 + b2 가 정상적으로 컴파일이 되야 하는지 모두 확인되었네요. ;-)
이 문제의 교훈은 아무리 namespace안이라 하더라도 모든 타입에 적용될 수 있는 함수의 사용은 다른 namespace에 있는 함수와 ADL 규칙에 의해 충돌할 수 있으므로 피해야 한다는 것이겠네요.
Comments
Post a Comment