Шаблоны C ++ - реализация вне класса - PullRequest
1 голос
/ 06 августа 2020

Рассмотрим следующее отклонение

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
{
   ...
};

Я хочу реализовать Stack::insert вне класса, поэтому я попробовал следующее

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

Теперь я получаю следующую ошибку

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

Я попытался перейти на следующий

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

, и теперь ошибка изменилась на

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

Я не понимаю, почему я получаю эту ошибку и как почини, надеюсь, что кто-то поможет

1 Ответ

0 голосов
/ 06 августа 2020

Я удивлен, что вы получаете указанную вами ошибку, потому что у вас есть очень очевидная синтаксическая ошибка в конструкторе в элементе данных:

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

Если T = int, приведенное выше будет преобразовано в int[4] что приводит к ошибке. Вероятно, вы хотите:

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

Предполагая, что это исправлено, мы наконец переходим к ошибке:

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

Это означает, что iterator - это тип, а вы не может напрямую получить к нему доступ с помощью оператора ::. Вы должны написать typename перед Stack<T, N>::iterator, чтобы компилятор знал, что вы хотите получить доступ к подтипу внутри Stack. Прочтите ответ. Где и почему мне нужно поместить ключевые слова «template» и «typename»? для более подробной информации.

Чтобы исправить это, измените функцию на:

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
{
  ...
}

Как вы, наверное, догадались, набирать столько текста - это довольно хакти c. Поэтому было введено ключевое слово auto, чтобы программист не набирал его каждый раз, когда он хочет его использовать:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...