title: Can't figure out what GCC 11.1 compiler error mean
body: <p>Why the code below does not compile with GCC 11.1?</p>
  <pre><code>#include &lt;stdexcept&gt;
  #include &lt;cassert&gt;
  #include &lt;initializer_list&gt;
  
  template &lt;class T, class Allocator = std::allocator&lt;T&gt;&gt;
  class ring
  {
  public:
  
      using value_type = T;
      using allocator_type = Allocator;
      using size_type = std::size_t;
      using difference_type = std::ptrdiff_t;
      using reference = T &amp;;
      using const_reference = const T &amp;;
      using pointer = T *;
      using const_pointer = const T *;
  
  private:
  
      template &lt;class E&gt;
      class ring_iterator
      {
      public:
  
          using iterator_category = std::random_access_iterator_tag;
          using value_type = E;
          using difference_type = std::ptrdiff_t;
          using reference = E &amp;;
          using pointer = E *;
  
          ring_iterator() : m_pRing(nullptr), m_pos(0) {}
          
          ring_iterator(const ring_iterator&amp; other) = default;
          ring_iterator(ring_iterator&amp;&amp; other) = default;
  
          ring_iterator&amp; operator = (const ring_iterator&amp; other) = default;
          ring_iterator&amp; operator = (ring_iterator&amp;&amp; other) = default;
  
          pointer operator-&gt; () const { return container().address&lt;E&gt;(m_pos); }
  
          reference operator* () const { return *m_pRing-&gt;address&lt;E&gt;(m_pos); }
  
      private:
  
          ring_iterator(const ring &amp; r, std::size_t pos) : m_pRing(&amp;r), m_pos(pos)
          {
          }
  
          const ring&amp; container() const
          {
              return *m_pRing;
          }
  
          const ring * m_pRing;
          
          //It can't be a pointer because there is no
          //end pointer in a circular buffer, so we use an index.
          std::size_t m_pos;
  
          friend ring;
      };
  
  private:
  
      template &lt;class E&gt;
      E * address(std::size_t pos) const
      {
          return nullptr;
      }
  
      template &lt;class E&gt;
      friend class ring_iterator;
  };
  
  using IntRing = ring&lt;int&gt;;
  </code></pre>
  <p>the error is</p>
  <pre><code>In member function ‘E* awl::ring&lt;T, Allocator&gt;::ring_iterator&lt;E&gt;::operator-&gt;() const’:
  error: expected primary-expression before ‘&gt;’ token
      pointer operator-&gt; () const { return container().address&lt;E&gt;(m_pos); }
  </code></pre>
  <p>but it starts to compile if I replace</p>
  <pre><code>pointer operator-&gt; () const { return container().address&lt;E&gt;(m_pos); }
  </code></pre>
  <p>with</p>
  <pre><code>pointer operator-&gt; () const { const ring&amp; r = container(); return r.address&lt;E&gt;(m_pos); }
  </code></pre>
  <p>what is the difference?</p>