2010-05-14 6 views
3

나는 같은 파일C++ 비 인라인 함수에서 사용하는 형식 정의는

template< typename T > 
typename vector<T>::const_reference // Line X 
vector<T>::at(size_type i) const 
{ 
    rangecheck(); 
    return elems_[ i ]; 
} 


template< typename T > 
reference        // Line Y 
vector<T>::at(size_type i) 
{ 
    rangecheck(); 
    return elems_[ i ]; 
} 

라인 X에서이

template< typename T > 
class vector { 
    public: 
    typedef T &  reference; 
    typedef T const & const_reference; 
    typedef size_t size_type; 

    const_reference at(size_t) const; 
    reference at(size_t); 

나중에 같은 클래스가 잘 컴파일이 있지만 라인 Y는 컴파일되지 않습니다. (버전 4.4.1) ++ g에서 오류 메시지는 다음과 같습니다이에서

foo.h:Y: error: expected initializer before 'vector' 

나는 그때 나는 완전히 라인 X에서 같은 형식 정의 이름을 한정 (비 인라인 함수를 갖고 싶어한다는 수집 size_type에는 아무런 문제가 없습니다.

그러나 적어도 제게는 X가 서투른 것처럼 보입니다.

대체 방법이 있습니까?

+0

답변이 잘못되었습니다. –

답변

4

예, 클래스 외부 멤버 함수 정의에서는 중첩 된 반환 형식에 대해 정규화 된 이름을 사용해야합니다. 이것은 BTW는 템플릿과 아무 관련이 없습니다. 비 템플릿 클래스에서도 마찬가지입니다.

여러분의 경우 템플릿 클래스이므로 종속 템플릿 클래스에서 중첩 된 형식을 참조하기 위해 정규화 된 이름을 사용하고 있으므로 키워드 typename을 앞에 붙여야합니다.

그러나 리턴 유형을 한정하기 만하면됩니다. 위해 (당신은뿐만 아니라 입력 매개 변수의 정규화 된 이름을 사용하도록 선택할 수 있습니다 매개 변수 유형

template< typename T > 
typename vector<T>::const_reference 
    vector<T>::some_method(const_reference r) const 
{ 
    // ... 
} 

을 규정 할 필요는 없지만,이 경우에는 반환 형식과 같은 일을해야 할 것 바로 그 이유) : 효과적인 C++ 항목 42에서 typename 키워드

template< typename T > 
typename vector<T>::const_reference 
    vector<T>::some_method(typename vector<T>::const_reference r) const 
{ 
    // ... 
} 
+0

@AndreyT : 매개 변수 유형은 템플릿 매개 변수에 따라 달라질 경우 정규화해야합니다. –

+0

@Eddy Pronk : 흥미 롭습니다. 나는 표준에서 확실한 답을 찾을 수 없었다. 그러나 Comeau Onine은 템플릿 클래스의 매개 변수 목록에서 * 부적합한 * 형식 이름을 성공적으로 찾습니다 (내가 옳다는 것을 암시 함). G ++ 또한 같은 방식으로 작동합니다.당신은 당신의 주장을 뒷받침 할 수있는 표준의 장소를 인용 할 수 있습니까? 나는 네가 틀렸다는 것을 말하는 것이 아니다. 또한, 나는 당신이 말하는 것이 완벽한 의미를 지니고 있으며, 예상 할 수있는 논리적 인 것이라고 말하고 싶습니다. 그러나 컴파일러는 동의하지 않습니다. – AnT

+0

@ AndreyT : 아직 표준에서 찾지 못했습니다. Effective C++ Item 42를 보았습니다. 제 대답을보십시오. –

2

정확합니다. 당신의 typedef가 전역 범위가 아닌 클래스의 범위에 주어지기 때문에 유형을 정규화해야합니다. 전 세계적 범위를 오염시키지 않으면 서 그것을 아름답게하는 어떤 방법이 있는지 모르겠다. 그것은 나쁜 생각 일 것이다. 그러나 함수가 매우 짧아서 인라인으로 정의하면 어떨까요? 그렇게하면 더 많은 타이핑을 줄일 수 있고, IMHO, 읽기가 더 쉽습니다.

3

으로 앞에 추가 : "템플릿에 중첩 의존 타입의 이름을 참조 언제, 당신은 즉시 워드 유형 이름하여 앞에 와야합니다." size_t는 템플릿 매개 변수에 종속 된 항목 안에 중첩되지 않습니다. 당신은 그것을 typedef했으나 항상 size_t가 될 것입니다.

size_type DID은 템플릿 매개 변수에 따라 달라집니다.

#include <cstddef> 

template< typename T > 
class vector { 
    public: 
    typedef T &  reference; 
    typedef T const & const_reference; 

    const_reference at(typename T::size_type) const; 
    reference at(typename T::size_type); 
}; 

template< typename T > 
typename vector<T>::const_reference 
vector<T>::at(typename T::size_type i) const 
{ 
    // ... 
} 

template< typename T > 
typename vector<T>::reference 
vector<T>::at(typename T::size_type i) 
{ 
    // ... 
} 

struct Foo 
{ 
    typedef size_t size_type; 
}; 

int main() 
{ 
    vector<Foo> f; 
    return 0; 
} 

size_type은 Foo의 중첩 유형입니다.

관련 문제