One of the problems Deducing this solves is duplication by making member functions cvref aware of the cvref-ness of the object the function is being called on. By declaring Alias templates (Template Typdefs) and returning them in the member functions rather than just returning auto are we not forced to have two iterator objects?
template <typename T>
struct const_list_iterator{
typedef const T& reference;
typedef const T* pointer;
reference operator*() const{/***/}
pointer operator ->() const{/***/}
};
and
template <typename T >
struct list_iterator{
typedef T& reference;
typedef T* pointer;
reference operator*(){/***/}
pointer operator ->(){/***/}
};
However, with Deducing this if the return type is auto can we simply have a single iterator object?
template <typename T>
struct list_iterator
template <typename itself>
auto operator*(this itself&& self){/***/}
template <typename itself>
auto operator->(this itself&& self){/***/}
};
Which we can use as below:
template <typename T>
struct list{
using iterator = list_iterator<T>;
auto begin() -> iterator {
iterator(node -> next);
}
auto begin() const -> iterator{
iterator(node -> next)
}
};
So, will using typedefs force us to duplicate iterator objects?
Your example code does not propagate
constcorrectly from the container to the iterator.begin() constwill return the same type asbegin(). So any deduction on theoperator*of the iterator is irrelevant; the fact thatconstwas involved has already been lost.In order to propagate the
constfrom the container'sbeginto the iterator,beginmust return a different type when the container is called viaconst. It could be a different specialization of the same iterator template (list_iterator<const T>, for example), but it needs to be a different type.You can give
beginan explicit object parameter and deduce theconst-ness from it. But it'd just be doing this:If the
if constexprcondition bothers you, you can stick it in a helper type metafunction: