Reputation: 333
I have a syntactic question rather,
With the following iterator class inside of a vector class,
#include <memory>
#include <cstddef>
#include <iterator>
namespace ft { template <class T, class Alloc = std::allocator<T> > class vector; }
template <class T, class Alloc>
class ft::vector
{
public:
typedef T value_type;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::pointer pointer;
typedef ptrdiff_t difference_type;
template <class value_type>
class ptr_iterator : public std::iterator<std::random_access_iterator_tag, value_type>
{
public:
ptr_iterator();
};
typedef ptr_iterator<value_type> iterator;
typedef ptr_iterator<const value_type> const_iterator;
};
How can I address the constructor of ptr_iterator
outside of the declaration?
I tried this way:
template <class T, class Alloc>
ft::vector<T, Alloc>::iterator::iterator() {}
But it yields
Vector.hpp:120:1: error: specializing member 'ft::vector<T, Alloc>::ptr_iterator<T>::iterator' requires 'template<>' syntax
ft::vector<T, Alloc>::iterator::iterator() {}
I attempted adding <> after both of the iterator
words and replacing the second iterator
word with ptr_iterator,
but it still doesn't compile.
Can I still use the typedef without repeating both templates above the function signature?
Or is there a better design for the iterator declaration that'll allow me to define both iterator and const_iterator?
Upvotes: 2
Views: 127
Reputation: 2963
For the out-of-line definition, you must unfortunately repeat the entire "signature" of all the nested templates, including constraints, if any. Cigien has given the right form:
template <class T, class Alloc>
template <class value_type>
ft::vector<T, Alloc>::ptr_iterator<value_type>::ptr_iterator()
{}
Since this can be messy and error-prone, you can also define the nested class inline, or alternatively as a non-nested helper class. In libstdc++, the former approach is taken for the iterators of views, but the latter for containers like std::vector
, for example:
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
Oh dear, I'm not sure if it's even possible to define an operator like that! Since it's a free function, it doesn't need the nested template parameters and I would put it in the ft
namespace. It would have to look like this:
namespace ft {
template <class T, class Alloc, class value_type>
bool operator==(
typename vector<T, Alloc>::template ptr_iterator<value_type> const& lhs,
typename vector<T, Alloc>::template ptr_iterator<value_type> const& rhs)
{ return true; }
}
However, I've tried this code on Compiler Explorer and my compiler complains that it cannot deduce the parameter(s) of the vector class.
Upvotes: 1