2016-09-29 4 views
0

필자는 전에는 반복기로 작업 해 본 적이 없으며 필자가 작성한 사용자 지정 컨테이너 클래스에 대한 사용자 지정 반복기를 디자인하는 데 문제가 있습니다.C++ 반복자 반환 유형

배경 :

class RandomArray 
{ 
friend ostream& operator<<(ostream&, const RandomArray&); 

public: 
    class iterator 
    { 
    public: 
     typedef iterator self_type; 
     typedef int* pointer; 
     typedef int& reference; 
     self_type operator++() { self_type i = *this; ptr++; return i;} 
     reference operator*() {return *ptr;} 
     bool operator!=(const self_type& rhs) {return ptr != rhs.ptr;} 
    private: 
     pointer ptr; 
    }; 

    class const_iterator 
    { 
    public: 
     typedef const_iterator self_type; 
     typedef int* pointer; 
     typedef int& reference; 
     self_type operator++() { self_type i = *this; ptr++; return i;} 
     const reference operator*() { return *ptr; } 
     bool operator!=(const self_type& rhs) {return ptr != rhs.ptr;} 
    private: 
     pointer ptr; 
    }; 

    RandomArray(); 

    RandomArray(size_t); 

    size_t size() const; 

    int* begin(); 
    iterator begin(); 

    const int* begin() const; 
    const iterator begin() const; 

    int* end(); 
    iterator end(); 

    const int* end() const; 
    const iterator end() const; 
private: 
    size_t capacity; 
    int* data; 
}; 

나 '오류 :

TEST(RandomArray, End) { 
    RandomArray r(17); 
    int *b = r.begin(); 
    int *e = r.end(); 
    EXPECT_EQ(b + 17, e); 
} 

TEST(RandomArray, IteratorTypedef) { 
    RandomArray r(7); 
    for (RandomArray::iterator it = r.begin(); it != r.end(); ++it) { 
     *it = 89; 
     EXPECT_EQ(89, *it); 
    } 
} 

가 여기 내 헤더 파일과 반복자에 대한 코드입니다 :이 내가 가진 두 개의 테스트 케이스를하고, 구글이 API를 테스트 사용 점점 시작과 끝이 다음과 같습니다 : Error: Cannot overload functions distinguished by return type alone.

다른 함수와 동일한 함수 이름과 매개 변수를 가질 수 없다는 것을 알고 있습니다. 이것을 할 수있는 더 좋은 방법이 있는지 궁금합니다. 나는 이터레이터를 올바르게 만들고 있는가? 템플릿으로이 문제를 해결할 수 있습니까? int*iterator을 모두 반환하려면 begin()end()이 필요하므로 두 가지 테스트 케이스를 모두 통과시킬 수 있습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

+1

포인터를 반환 제거 만 반복자를 반환하기? – NathanOliver

+0

그리고 테스트 케이스를 수정하십시오. 그들이 요구하는 것은 불가능합니다. – ubik

답변

2

나는 둘 모두 int*iterator 그래서 난 모두 테스트 케이스를 통과 할 수 반환 begin()end()이 필요합니다.

아니요. 포인터가 예상되는 테스트 케이스가 잘못되었습니다. 컨테이너는 다시 반복자를 제공합니다. 귀하의 경우 반복자는 이 될 수 있습니다. 포인터이지만 구현 세부 사항입니다.

iterator begin(); 
const_iterator begin() const; // NB: const_iterator, not const iterator 

을 그리고 RandomArray::iterator 대신 int*을 기대하는 당신의 단위 테스트를 해결 : 당신은 확실히 불과합니다. 또는 더 나은 것은 auto입니다.


참고 : 귀하의 operator++()은 후위 증가 대신 접두사 증가 않습니다. 또한 const reference은 잘못된 유형이고, 그 값은 int& const이며 참조는 본질적으로 const입니다. reference에 대한 typedef를 int const&으로 변경하고 싶습니다.

0

다음 있도록하거나 필요 (이 있지? 왜 새로운 클래스 인 경우이지만) 당신의 반복자 유형 포인터 유형, 또는-변환 가능하면 int *b = r.begin(); 테스트 케이스를 변경할 수없는 경우 포인터 타입.

첫 번째 경우에는 iterator 클래스를 제거하고 using iterator = int*;using const_iterator = int const*;으로 작성하십시오.

두 번째 경우에는 변환 함수 operator pointer() const { return ptr; }을 추가하십시오.

두 번째 경우가 더 좋습니다. 앞으로이 기능을 사용 중지해야 할 수 있습니다. 그러나 iterator 타입을 사용하도록 테스트 케이스를 수정하는 것이 더 낫다.

0

내가 잘못한 것을 알았습니다. 필자가해야만하는 것은 typedef 반복자를 int *로 선언해야한다는 것입니다.그런 다음

class MyClass 
{ 
public: 
    int* begin(); 

    const int* begin() const; 

    int* end(); 

    const int* end() const; 

    //HERE 
    typedef int* iterator; 
    typedef const int* const_iterator; 
private: 
    size_t capacity; 
    int* data; 
}; 

함수 본문에 나는이 그것을 변경 :

코드 업데이트

int* MyClass::begin() 
{ 
    return iterator(&data[0]); 
} 

const int* MyClass::begin() const 
{ 
    return const_iterator(&data[0]); 
} 

int* MyClass::end() 
{ 
    return iterator(&data[capacity]); 
} 

const int* MyClass::end() const 
{ 
    return const_iterator(&data[capacity]); 
} 
+0

'iterator (& data [0])'는'iterator (data)'가'data'와 같은 것을 말합니다. 모든 여분의 것들에 대한 필요가 없습니다. – Barry