Search code examples
c++templatesiteratorcontainersconst-iterator

Cannot convert custom iterator to const_iterator


I am coding an implementation/copy of the std::vector container, and I am having some issues with its iterators.

My random_access_iterator and vector class are implemented like this:

namespace ft
{
    template <typename T>
    class random_access_iterator
    {
        public:
            typedef T value_type;
            typedef value_type* pointer;
            // [...]

        private:
            pointer _ptr;

        public:
            random_access_iterator( void ) : _ptr(pointer()) {}
            random_access_iterator( const random_access_iterator& src ) { *this = src; }
            random_access_iterator& operator= ( const random_access_iterator& src ) { this->_ptr = src._ptr; return *this; }
            // [...]
    };

    template<class T>
    class vector
    {
        public:
            typedef T value_type;
            typedef random_access_iterator<value_type> iterator;
            typedef random_access_iterator<const value_type> const_iterator;
            // [...]

        public:
            vector( void ) {}
            // [...]
    };
}

int main()
{
    ft::vector<int>::iterator it;
    ft::vector<int>::const_iterator cit(it);
    return 0;
}

The Copy Constructor of random_access_iterator<const int> receiving a random_access_iterator<int> in the main function results in a compile-time error:

iterator_test.cpp: In function ‘int main()’:
iterator_test.cpp:39:47: error: no matching function for call to ‘ft::random_access_iterator<const int>::random_access_iterator(ft::vector<int>::iterator&)’
   39 |         ft::vector<int>::const_iterator cit(it);
      |                                               ^
iterator_test.cpp:16:25: note: candidate: ‘ft::random_access_iterator<T>::random_access_iterator(const ft::random_access_iterator<T>&) [with T = const int]’
   16 |                         random_access_iterator( const random_access_iterator& src ) { *this = src; }
      |                         ^~~~~~~~~~~~~~~~~~~~~~
iterator_test.cpp:16:79: note:   no known conversion for argument 1 from ‘ft::vector<int>::iterator’ {aka ‘ft::random_access_iterator<int>’} to ‘const ft::random_access_iterator<const int>&’
   16 |                         random_access_iterator( const random_access_iterator& src ) { *this = src; }
      |                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
iterator_test.cpp:15:25: note: candidate: ‘ft::random_access_iterator<T>::random_access_iterator() [with T = const int]’
   15 |                         random_access_iterator( void ) : _ptr(pointer()) {}
      |                         ^~~~~~~~~~~~~~~~~~~~~~
iterator_test.cpp:15:25: note:   candidate expects 0 arguments, 1 provided

I am using c++ file.cpp -std=c++98 to compile.

For your information, I am not allowed to use anything newer than C++98. I would be very thankful if any of you could explain to me why this is wrong and what I could do to make it behave like the SDL.


Solution

  • I managed to make it work by replacing the CopyConstructor and CopyAssignementOverload with

    template<typename U>
    random_access_iterator( const random_access_iterator<U>& src ) { *this = src; }
    template<typename U>
    random_access_iterator& operator= ( const random_access_iterator<U>& src ) { this->_ptr = src._ptr; return *this; }
    

    and by adding a template<typename U> friend class random_access_iterator; private member