1

Consider the following decleration

template<class T, int N>
class Stack 
{
public:
    Stack() : T[N]{} {};
    class iterator;
    iterator insert(iterator it, const T &v);
private:
    T[N];
};

template<class T, int N>
class Stack<T,N>::iterator
{
   ...
};

I want to implement Stack::insert outside the class, so I tried the following

template<class T, int N>
Stack::iterator Stack<T, N>::insert(Stack::iterator p, const T &v)
{
    ...
}

Now I get the following error

'Stack' is not a class, namespace, or enumeration

I tried to change to the following

template<class T, int N>
Stack<T, N>::iterator Stack<T, N>::insert(Stack::iterator p, const T &v)
{
    ...
}

and now the error changed to

Missing 'typename' prior to dependent type name 'Stack<T, N>::iterator'

I don't understand why I get this error and how to fix it, hope that someone can help

david
  • 11
  • 1
  • 4
    Have you read this? [c++ - Where and why do I have to put the "template" and "typename" keywords? - Stack Overflow](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords?rq=1) – user202729 Aug 06 '20 at 07:53
  • "I don't understand why I get this error and how to fix it" While the first is excusable, the error message tells you exactly what you need: `typename Stack::iterator` – Caleth Aug 06 '20 at 08:35
  • Unrelated, maybe look into [`std::array`](https://en.cppreference.com/w/cpp/container/array) instead of `T[N]`. – Olaf Dietsche Aug 06 '20 at 08:40

1 Answers1

0

I am surprised that you are getting the error you said because you have a very obvious syntax error in the constructor in data member:

    Stack() : T[N]{} {};  // T[N] isn't valid!
    T[N];                 // same!

If T = int, the above would translate to int[4] resulting in the error. What you probably want is:

    Stack() : arr{} {}  
    T arr[N];                 

Assuming this is fixed, we finally get to the error:

Missing 'typename' prior to dependent type name 'Stack<T, N>::iterator'

What this is saying is that iterator is a type and you can't directly access it using :: operator. You have to write typename before Stack<T, N>::iterator so that the compiler knows you want to access the subtype inside Stack. Read the answerWhere and why do I have to put the “template” and “typename” keywords? for more details.

To fix this, change the function to:

template<class T, int N>
typename Stack<T, N>::iterator Stack<T, N>::insert(typename Stack::iterator p, const T &v)
//^^typename here                                  ^^ and here
{
  ...
}

As you can probably feel that typing so much is quite hectic. Hence auto keyword was introduced to save the programmer from typing these out everytime he wants to use it:

  Stack<int,4>::iterator i = s.insert(it, 3); // imagine typing this everytime
  //use auto
  auto it = s.insert(iterator, 3); //good

Waqar
  • 8,558
  • 4
  • 35
  • 43