1

I tried to do this

template <class V>
class myiterator: std::iterator<std::random_access_iterator_tag, V>{
    reference a;
};

Like in this example

class myiterator: std::iterator<std::random_access_iterator_tag, int>{
    reference a;
};

But I got an error "‘reference’ does not name a type". How can I use std::iterator<>::reference with templates ?

user
  • 44
  • 7
  • [Where and why do I have to put the “template” and “typename” keywords?](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – IWonderWhatThisAPIDoes May 25 '21 at 17:47

2 Answers2

1

The name reference won't be found because nondependent name won't be looked up in dependent base class std::iterator<std::random_access_iterator_tag, V>, which depends on template parameter V.

You can make reference a dependent name as:

template <class V>
class myiterator: std::iterator<std::random_access_iterator_tag, V>{
    typename std::iterator<std::random_access_iterator_tag, V>::reference a;
};

On the other hand the non-template version doesn't have such issue.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

The name reference is declared in the base class, and the base class is a dependent type (its type depends on V). There are special rules that apply to this situation: when the compiler sees the name reference, it does not search the dependent base class scope, and therefore, does not find the name. In order to force the compiler to search dependent base class scopes, you must qualify the name.

You might think that iterator::reference would do the trick. Unfortunately, this doesn't work either. iterator as a shorthand for std::iterator<std::random_access_tag, V> is itself declared inside the base class as its "injected class name". So iterator will not be found either unless it is qualified by something.

You can type it out the long way: typename std::iterator<std::random_access_tag, V>::reference a;. A more readable way is:

using base = typename myiterator::iterator;
typename base::reference a;

You can use base:: to force lookup in the base class scope during the rest of the myiterator class definition.

In C++20, typename can be omitted from these contexts.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312