Какой правильный синтаксис для функции-члена шаблона класса, возвращающего тип, определенный в этом классе? - PullRequest
1 голос
/ 24 марта 2011

Я сейчас работаю через Accelerated C ++ и застрял в упражнении 11-6. Идея состоит в том, чтобы переопределить стандартный библиотечный вектор как класс с именем Vec.

У меня проблемы с членом iterator erase(iterator), потому что я не знаю правильный синтаксис вне определения класса, и все, что я пробовал, приводит к ошибке компилятора. Код, который у меня сейчас есть:

template <class T> T* Vec<T>::erase(T* pos){

    if(pos < avail)
        std::copy(pos + 1, avail, pos);

    --avail;
    alloc.destroy(avail);

    return pos;

}

Это отлично работает. Тем не менее, в целях удобства обслуживания и совместимости с алгоритмами в stl, я знаю, что должен делать что-то вроде этого:

template <class T> Vec<T>::iterator Vec<T>::erase(Vec<T>::iterator pos){

    // As before

}

Я уже определил iterator в определении класса следующим образом:

 typedef T* iterator;

Попытка скомпилировать со вторым фрагментом кода приводит к:

D:\Documents\Programming\Accelerated C++\Chapter 11>cl /EHsc Vec.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

Vec.cpp
Vec.cpp(23) : warning C4346: 'Vec<T>::iterator' : dependent name is not a type prefix with 'typename' to indicate a type
Vec.cpp(23) : error C2143: syntax error : missing ';' before 'Vec<T>::erase'
Vec.cpp(23) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Vec.cpp(23) : fatal error C1903: unable to recover from previous error(s); stopping compilation

К сожалению, предупреждение не имеет особого смысла для меня, и после прочтения страницы MSDN для него Я не могу точно понять, как оно будет применяться к моему коду.

Остальные сообщения выглядят так, как будто компилятор не распознал тип возврата.

Я пробовал много разных комбинаций, и поиск не очень помог. Буду признателен за любую помощь. Спасибо!

Ответы [ 2 ]

7 голосов
/ 24 марта 2011
  template <class T> 
  typename Vec<T>::iterator Vec<T>::erase(typename Vec<T>::iterator pos){
 //^^^^^^^^ note this                      ^^^^^^^^ note this as well!

       //your code!
  }

То есть typename требуется в двух местах.Это потому, что iterator является зависимым именем, поэтому typename требуется!

Прочитайте это превосходное объяснение от великого парня по имени Йоханнес о самом Stackoverflow:

После прочтения вы также можете прочитать эту тему:


Ссылки на другие полезные статьи:

3 голосов
/ 24 марта 2011
template <class T> typename Vec<T>::iterator Vec<T>::erase(typename Vec<T>::iterator pos){

    // As before

}

... потому что итератор здесь - это имя , зависящее от параметра шаблона "без typename, компилятор делает вид, что Vec :: iterator является статическим членом Vec:)

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