1. 자격 없는 이름 (Unqualified Name)
자격 없는 이름(unqualified name)은 특정 클래스나 네임스페이스를 명시하지 않고 사용하는 이름을 의미합니다. 자격이 없다는 것은 컴파일러가 해당 이름을 해석할 때 이름이 속한 범위를 명확히 지정하지 않았다는 뜻입니다. 이러한 이름은 현재의 스코프(범위)에서 자동으로 해석됩니다. 예를 들어, 함수나 변수를 단순히 이름만으로 호출하거나 사용하는 경우가 이에 해당합니다.
예시
int value = 10;
void foo() {
int x = value; // 자격 없는 이름 'value' 사용
}
위 코드에서 value는 자격 없는 이름입니다. foo() 함수 내부에서 value가 전역 변수를 참조하지만, 이 경우 ::value처럼 전역 범위임을 명시하지 않았기 때문에 컴파일러가 자동으로 현재 스코프부터 전역 스코프까지 찾아갑니다. 이때 동일한 이름의 지역 변수가 있다면 먼저 지역 변수를 참조합니다.
2. 템플릿 클래스에서의 문제
템플릿 클래스에서 자격 없는 이름을 사용할 때는 예상과 다른 동작이 발생할 수 있습니다. 예를 들어, 기본 클래스 B<T>의 멤버를 상속받은 파생 클래스 A<T>에서, 자격 없는 이름을 사용할 경우 전역 범위에 같은 이름이 있으면 컴파일러가 전역 범위의 이름을 선택할 수 있습니다.
예시 (템플릿 클래스에서 자격 없는 이름 사용)
typedef int Type; // 전역 범위에 정의된 Type
template<typename T> struct B {
typedef T Type; // 기본 클래스 B<T>의 Type
};
template<typename T> struct A : B<T> {
void foo() {
Type t = 0; // 자격 없는 이름 사용, 전역의 ::Type(int)을 참조
}
};
위 코드에서 Type은 자격 없는 이름으로 사용되었고, 이 경우 컴파일러는 전역에 있는 ::Type을 참조합니다. 하지만 개발자가 의도한 것은 기본 클래스 B<T>의 Type일 수 있습니다. 이 문제를 해결하기 위해 자격 있는 이름을 사용해야 합니다.
3. 템플릿 클래스에서 자격 있는 이름 사용법
템플릿 상속에서 자격 있는 이름을 사용할 때는 typename 키워드나 this->를 활용하여 의도한 멤버를 명확히 지정할 수 있습니다.
해결 방법 1: this-> 사용
template<typename T> struct A : B<T> {
void foo() {
this->Type t = 0; // 기본 클래스의 Type을 명확히 참조
}
};
이처럼 this->를 붙여 사용하면 기본 클래스의 멤버를 참조한다는 것을 명확히 할 수 있습니다.
해결 방법 2: typename 키워드 사용
또 다른 방법은 typename 키워드를 활용하는 것입니다. 템플릿에서 B<T>::Type과 같이 기본 클래스의 멤버 타입을 사용할 때는 typename을 앞에 붙여야 합니다.
template<typename T> struct A : B<T> {
void foo() {
typename B<T>::Type t = 0; // 기본 클래스 B<T>의 Type을 명확히 참조
}
};
4. C++ 이름 검색 규칙
C++에서는 이름을 검색할 때 현재 스코프부터 시작해 점차 상위 스코프로 확장하여 찾는 규칙을 따릅니다. 이러한 규칙은 코드의 유지보수와 가독성을 높이지만, 자격 없는 이름을 사용할 경우 의도치 않게 전역 변수를 참조하거나 상위 클래스 멤버를 찾지 못하는 문제가 발생할 수 있습니다. 이 때문에, 특히 템플릿 코드에서는 명확한 범위를 지정하는 것이 중요합니다.
요약
- 자격 없는 이름 (Unqualified Name): 특정 범위를 명시하지 않고 사용하는 이름. C++은 가장 가까운 스코프부터 시작해 이름을 찾습니다.
- 템플릿 클래스에서의 충돌 방지: this->나 typename 키워드를 사용하여 의도한 멤버를 명확히 지정할 수 있습니다.
템플릿 클래스에서 자격 없는 이름 사용은 전역 범위와 충돌할 가능성이 높으므로, 코드를 명확하게 작성하는 것이 중요합니다.
'C++' 카테고리의 다른 글
[C++] this-> 접두사 (1) | 2024.11.04 |
---|---|
[C++] 정규 이름 조회(qualified lookup) (0) | 2024.10.29 |
[C++] 네임스페이스(namespace) (0) | 2024.10.27 |
[C++] 중첩 호출(nested call) (0) | 2024.10.25 |
[C++] 유일 정의 규칙(one definition rule/ODR) (0) | 2024.10.24 |