Item 42: Understand the two meanings of typename

모르핀·2021년 4월 19일
0

C++기초

목록 보기
6/7

템플릿 매개변수를 선언하는 경우의 class 및 typename은 같은 의미 지닌다.

template<class T> class Widget;

template<typename T> class Widget;

다음 코드에서 C::const_iterator처럼 매개변수인 C에 의존적인 것들을 의존 이름(dependent name)이라고 합니다. 그리고 의존 이름이 어떤 클래스 안에 중첩되어 있는 경우에는 중첩 의존 이름(nested dependent name)이라고 부릅니다.

template<typename C>
void print2nd(const C& container)
{
    if (container.size() >= 2) 
    {
        C::const_iterator iter(container.begin());
        int value = *iter; std::cout << value;
    }
}

구문 분석기는 템플릿 안에 중첩 의존 이름을 만나면 타입이라고 알려 주지 않는 한 그 이름이 타입이 아니라고 가정한다. 그래서 다음 코드에서 C::const_iterator는 타입이 아니라고 해석된다.

template<typename C> void print2nd(const C& container) 
{
    if (container.size() >= 2) 
    {
        C::const_iterator iter(container.begin());
        ...

이를 해결하기 위해여 typename 키워드를 이용해서 typename C::const_iterator로 고친다면, C::const_iterator는 타입이 됩니다.

template<typename C> void print2nd(const C& container) 
{
    if (container.size() >= 2) 
    {
        typename C::const_iterator iter(container.begin());
        ...
template<typename IterT> void workWithIterator(IterT iter) 
{
    typedef typename std::iterator_traits<IterT>::value_type value_type;
    
    value_type temp(*iter); 
    ...
}

이처럼 typename키워드는 중첩 의존 이름을 식별하는 용도에 써야합니다.

하지만 이러한 규칙에도 예외는 존재합니다.
다음과 같이 기본 클래스의 리스트에 있거나 초기화 리스트 내의 기본 클래스의 식별자로서 있을 경우 typename을 붙여주면 안 된다.

template<typename T> class Derived : public Base<T>::Nested  
// base class list: typename not allowed
{ 
public:
    Derived(int x) : Base<T>::Nested(x) 
    {
        typename Base<T>::Nested temp; ...
    } ...
};
profile
플어머

0개의 댓글