2012-02-15 2 views
0

iterator가있는 사용자 지정 STL 호환 컨테이너를 구현하려는 것은 처음이지만 템플릿 구문 및 사용법에 문제가 있습니다.기본 매개 변수가있는 C++ 템플릿

namespace unstd { 

template<typename T,class Allocator = std::allocator<T>> 
class SList 
{ 

public: 

    typedef typename Allocator::value_type value_type; 
    typedef typename size_t size_type; 
    typedef typename Allocator::template rebind<T>::other allocator_type; 
    typedef typename Allocator::reference reference; 
    typedef typename Allocator::const_reference const_reference; 
    typedef typename T* pointer; 
    typedef typename const T* const_pointer; 
    typedef typename ptrdiff_t difference_type; 

    typedef typename SList_Iterator_Forward<T> iterator; 
    typedef typename const SList_Iterator_Forward<T> const_iterator; 

.... 
     /*----- ITERATORS -------*/ 
    iterator begin(); 
    ... 
    };} 

가의 시작 예를 들어 살펴 보자() 메소드 : 이 내 헤더 파일의 일부입니다. 내가 쓴 컴파일하지 않는다 (A .cpp 파일에서) 다음

template<typename T, class Allocator> 
iterator SList<T,Allocator>::begin() 
{ 

} 
//neither the following compile 
template<typename T, class Allocator> 
SList<T,Allocator>::iterator SList<T,Allocator>::begin() 
{ 

} 

을 나는 몇 가지 질문이 있습니다

  1. 이 컴파일되지 않습니다 왜? (오류 C2143 구문 오류 : 'token2'앞에 'token1'이 없습니다.)
  2. 왜 모든 템플릿 매개 변수를 명시 적으로 지명해야합니까? (즉, Allocator가 기본값을 가지고 있다는 점을 감안할 때 T 만 지정할 수는 없습니까?)
  3. 이 상황에서 구현 헤더를 분리하는 것이 옳은가요? 몇 가지 이유를 들어
+0

_STL은 (는) C++ 표준 라이브러리가 아닙니다. – Griwes

+0

해당 오류 메시지는 코드 –

답변

2

1)

template<typename T, class Allocator> 
typename SList<T,Allocator>::iterator SList<T,Allocator>::begin() 
^^^^^^^^ 

은 자극적이지만, 그것에 익숙해. 컴파일러는 템플릿과 같은 모든 것들은 변수라고 가정합니다. 그래서 타입이라면 특별히 말해야합니다.

2) 컴파일러는 함수 정의가 두 개의 템플릿 매개 변수가있는 SList 클래스 용이며 둘 다 어떤 것도 될 수 있음을 알아야합니다. 이것은 전문화가 아닙니다. 나는 당신의 디폴트가 실종되었다는 것을 알고 있으며, 디폴트가 없다면 모호하지는 않을 것이다. 그러나 나는 그것이 주로 컴파일러를 단순화하는 것이라고 생각한다.

3) 정의 은 별도의 파일에 포함될 수 있지만 자체 "번역 단위"(컴파일 된 파일 .cpp 및 포함)는 아닙니다. 따라서 .cpp에 넣지 마십시오. 혼란 스럽습니다. 템플릿 정의가 헤더의 맨 아래에 포함 된 .incl 파일에있는 것이 일반적입니다. 이렇게하면 컴파일러가 행복해지며 선언과 정의가 분리됩니다.

+0

감사합니다 .. 그 컴파일 오류를 해결. – Heisenbug

+0

그냥 마지막 질문 : "정의는 별도의 파일에있을 수 있지만 컴파일 된 파일에는 없습니다." 하지만 파일이 컴파일되지 않으면 어떻게 컴파일 할 수있는 방법을 시작할 수 있습니까? 템플릿을 cpp 파일로 사용되는 곳으로 컴파일 된 것 같아요? – Heisenbug

+0

@Heisenbug : 나는 나쁜 표현을 사용했다. 템플릿 함수 정의는 자체 번역 유닛에있을 수 없으므로 호출해야하는 _every_ 번역 단위에 있어야합니다. 일반적인 방법은 헤더에서 .inlc 파일을 포함시키는 것입니다. 번역 단위는 컴파일 된 파일 (일반적으로 .cpp)이며 포함 된 모든 것입니다. –

1
  1. :

    • 당신은 반환 형식 begin

    • iteratoriterator 앞에 SList<T,Allocator>:: 누락은 당신이 typename 필요 있도록 의존의 형태입니다 전면은 SList<T, Allocator>::iterator입니다.

    • 반환 유형이 void이 아닌 함수에서 값을 반환하지 않습니다. 너는 뭔가를 돌려 줄 필요가있어.

  2. 이름 SList<T, Allocator>이며 형식 이름 Allocator를 참조 할 수 있어야 때문에, 컴파일러에게 클래스의 전체 이름을 알려 주어야하고, 그 때문에 그것이 얼마나 때문에.

  3. 컴파일러가 템플릿의 구현이 선언과 동일한 파일에 있어야하므로 (템플릿의 일반성을 나타내는 명시 적 인스턴스화를 수행하지 않는 한) 사용자 정의 템플릿을 구현할 수 없습니다. 따라서 #include을 인터페이스 파일에 구현해야합니다.

+0

과 (과) 일치하지 않습니다. 정보를 제공해 주셔서 감사합니다. 무슨 요점에 대한 포인트 3 : 나는 머리말에 포함되지 않은 분리 된 파일로 구현되어 있기 때문에 잘못하고있다. @Mooing Duck 제안은 잘 컴파일 된 것으로 보입니다. 런타임 문제가 예상 되나요? 왜 컴파일러는 이것에 대해 불평하지 않습니까? – Heisenbug

+0

@Heisenbug 당신은 실제로 프로그램에서 수업을 실제로 사용하려고 시도 했습니까? (즉, 'SList '유형의 다른 .cpp 파일에서 변수를 만드는 것) –

+0

Carneige : 아, 다시 컴파일을 잊어 버렸을 수도 있습니다. 이제 링커 오류가 발생했습니다. 덕분에 많이 – Heisenbug

관련 문제