My compiler is updating to gcc11, and has started throwing errors for this code that was compiling before:
#include <list>
#include <map>
template < class Key, class T, class Compare = std::less<Key> >
struct cache_map
{
public:
//! The type of items in this cache_map
typedef std::pair<const Key, T> value_type;
private:
// list of pairs: (key, data): [lru] ---> [mru]
typedef std::list<value_type> list_type;
// map: key -> list_iter
typedef std::map<Key, typename list_type::iterator, Compare> map_type;
// An iterator implementation based on list_type::iterator.
template<class Iterator>
class iterator_impl : Iterator
{
friend class cache_map<Key, T, Compare>;
typedef Iterator base;
base& base_reference() { return static_cast<base&> (*this); }
const base& base_reference() const { return static_cast<const base&> (*this); }
public:
using base::difference_type;
using base::iterator_category;
using base::value_type;
using base::pointer;
using base::reference;
using base::operator*;
using base::operator->;
template<class I>
iterator_impl(iterator_impl<I> i) : base(i.base_reference()) { }
explicit iterator_impl(const base& i) : base(i) {}
iterator_impl() : base() { }
template<class I>
bool operator==(const iterator_impl<I>& other) const
{
return base::operator== (other.base_reference ());
}
template<class I>
bool operator!=(const iterator_impl<I>& other) const
{
return base::operator!= (other.base_reference ());
}
}
public:
//! An iterator for the range [lru] ---> [mru].
typedef iterator_impl<typename list_type::iterator> iterator;
//! An iterator for the range [lru] ---> [mru].
typedef iterator_impl<typename list_type::const_iterator> const_iterator;
}
The error message complains that != isn’t a member of iterator_impl: error: 'operator!=' is not a member of 'cache_map<int, bool>::iterator_impl<std::_List_const_iterator<std::pair<const int, bool> > >::base'
If I remove the != operator, I get the same thing for the == operator.
I saw that this gcc commit removed the inline == and != operators for list iterators (lines 342-353). I assume this is why I’m getting an error, because my code is trying to use the operators from base, which is an alias of the std::list iterator type. The code compiles when I change it to manually make the == and != comparisons, as shown below:
template<class I>
bool operator==(const iterator_impl<I>& other) const
{
return this->base_reference() == other.base_reference ();
}
template<class I>
bool operator!=(const iterator_impl<I>& other) const
{
return this->base_reference() != other.base_reference ();
}
My question is, is this a bug in gcc11? It seems like it may have been an accident to remove the operators without adding them back.