7

Below is code for my String class. I want to implement reverse_iterator and rbegin() and rend() methods. Have pasted code for assign method.


String::reverse_iterator rbegin = str2.rbegin();
String::reverse_iterator rend = str2.rend();
for (String::reverse_iterator b = rbegin; b != rend; ++b) {
    cout << *b;
}

class String {//my custom string class

public:

    class iterator :public std::iterator<std::random_access_iterator_tag, char> {
    public:
        iterator() :ch(NULL) {}
        iterator(const iterator& it) : ch(it.ch) {}

        char& operator*() { return *ch; }
        iterator& operator++() {
            ch = ch + 1;
            return *this;
        }
        bool operator==(const iterator& rhs) {
            return ch == rhs.ch;
        }
        bool operator!=(const iterator& rhs) {
            return ch != rhs.ch;
        }

    private:
        friend class String;
        iterator(char* c) :ch(c) {}
        char* ch;
    };
    explicit String();
    String(const String& str);
    String(const char* s);
    ~String();
    iterator begin();
    iterator end();
private:
    char* _string;
    size_t _length;
    size_t _capacity;
};

//iterator to end
String::iterator String::end() {
    //return iterator();
    if (_length == 0) {
        return iterator(_string);
    }
    else {
        return iterator(_string + _length + 1);
    }
}
void String::assign(const char* str) {
    if (sizeof(str) >= max_size()) {
        throw std::bad_alloc("String size is greater than max size");
    }
    if (_string != NULL) {
        delete[] _string;
    }
    _length = strlen(str);
    _capacity = _length < 5 ? 5 : _length;
    _string = new char[_capacity + 1];
    memset(_string, 0, _capacity + 1);
    memcpy(_string, str, _length);
}

int main() {
    String str2;
    str2.assign("This is assigned");
    String::iterator begin = str2.begin();
    String::iterator end = str2.end();
    //below loop should print "This is assigned" and is working fine
    for (String::iterator b = begin; b != end; ++b) {
        cout << *b;
    }

    return 1;
}
9
  • why cann't end be used as rbegin, begin as rend, and convert the string to char array so you can access the array by index? Commented May 18, 2013 at 13:23
  • i tried using this but it printed junk characters and run time error. Problem is with rend.Begin points to first char of string but rend should point to one location before begin Commented May 18, 2013 at 13:37
  • i see....do you mind sharing your begin? Commented May 18, 2013 at 13:41
  • //iterator to beginning String::iterator String::begin() { return iterator(_string); } Commented May 18, 2013 at 13:44
  • i do not know if you care about changing the original string or use additional memory. If not, reverse the string or store the reverse in another string...and then you can use your begin and end as rbegin and end. Commented May 18, 2013 at 13:44

1 Answer 1

13

Reverse iterators can be implemented in terms of bidirectional iterators:

typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

reverse_iterator rbegin()
{
  return reverse_iterator(end());
}

reverse_iterator rend()
{
  return reverse_iterator(begin());
}

... and then the same for const iterators

However, your forward iterator implementation needs to be bidirectional, meaning that it must also support the -- operator:

iterator& operator--() 
{
    --ch;
    return *this;
}
Sign up to request clarification or add additional context in comments.

2 Comments

this is giving error for overloaded operator==(const iterator& rhs) for iterator class. Error message is "no operator found which takes a left-hand operand of type 'const String::iterator'"
bool operator == (const iterator&) is supposed to have a const qualifier

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.