Как создать объект STL итераторов типа шаблона?

Как создать объект STL итераторов типа шаблона? Я пытаюсь создать объект STL (скажем, вектор) итераторов типа шаблона, как показано ниже.

vector<vector<T>::iterator> it1;

Это не работает как в g++, так и в VC++, где. Оба компилятора говорят почти одно и то же

г++

Main.cpp:8:49: error: type/value mismatch at argument 1 in template parameter li
st for `template<class _T1, class _T2> struct std::pair'
Main.cpp:8:49: error:   expected a type, got `std::vector<T>::iterator'

VС++

error C2923: 'std::vector' : 'std::vector<T>::iterator' is not a valid template type argument for parameter '_Ty'

Конечно, если вы создаете итератор Concrete Type, он работает, например.

vector<vector<int>::iterator> it1;

Вот минимальный неудачный пример

#include<vector>
#include<iterator>
using namespace std;
template<typename T>
class Spam {
public:
    vector<vector<int>::iterator> it1; #Compiles Fine
    vector<vector<T>::iterator>   it2; #Fails
    };

ПРИМЕЧАНИЕ

Из ответов я понял, что если тип зависим, то нужно префикс ключевых слов typename. Если это так, то

vector< vector<T>  >  it;

также должен потерпеть неудачу, но это не так. Кажется, что это терпит неудачу и требует typename ключевых слов, если зависимое имя является typedef


person Abhijit    schedule 01.05.2012    source источник
comment
Ваше ПРИМЕЧАНИЕ неверно. Любое зависимое имя, которое называет тип, потребует typename, но в случае vector<vector<T> > зависимого имени нет. (Ни vector, ни T нет)   -  person MSalters    schedule 01.05.2012


Ответы (3)


Вам нужно использовать typename как:

vector<typename vector<T>::iterator>   it2; 

Это потому, что iterator является зависимым именем, так как оно зависит от аргумента шаблона T.

В качестве примечания имейте в виду, что итераторы вектора становятся недействительными, когда вектор изменяет свой размер. Таким образом, вектор таких итераторов может оказаться не таким полезным, как вы можете подумать. Чтобы сделать такой вектор полезным, убедитесь, что вектор никогда не меняет свой размер, чьи итераторы вы собираетесь хранить в этом векторе итераторов.

person Nawaz    schedule 01.05.2012
comment
Что я понял из ответов, так это то, что если тип зависим, то нужно префикс ключевых слов typename. Если это так, то vector‹ vector‹T› › это; также должен потерпеть неудачу, но это не так. Кажется, что это терпит неудачу и требует typename ключевых слов, если зависимое имя является typedef - person Abhijit; 01.05.2012
comment
@Abhijit: vector< vector<T> > не является зависимым именем. Зависимые имена — это вложенные имена в форме SomeType<T>::SomeName; здесь SomeName — зависимое имя. - person Nawaz; 01.05.2012

Вы должны добавить ключевое слово typename:

vector<typename vector<T>::iterator>   it2; 

Эта страница больше всего помогла мне понять ее.

person Stephan Dollberg    schedule 01.05.2012
comment
Что я понял из ответов, так это то, что если тип зависим, то нужно префикс ключевых слов typename. Если это так, то vector‹ vector‹T› › это; также должен потерпеть неудачу, но это не так. Кажется, что это терпит неудачу и требует typename ключевых слов, если зависимое имя является typedef - person Abhijit; 01.05.2012
comment
@Abhijit, ты на полпути. Он должен быть не только зависимым, но и квалифицированным, чего vector< vector<T> > нет. Я снова могу только порекомендовать ссылку, которую я разместил, там очень хорошо объяснено. - person Stephan Dollberg; 01.05.2012
comment
@Abhijit vector< vector< T > > не может быть ничем иным, как типом, в то время как vector< T >::iterator вполне может быть чем-то другим. В последнем случае вам нужно сообщить компилятору, что вы ожидаете тип. - person Andrew Durward; 01.05.2012

Это было задано в ближайшее время много раз ...

 vector<typename vector<T>::iterator>

Проблема в том, что вложенный тип iterator зависит от аргументов вашего шаблона, поэтому вам нужно сообщить компилятору, что это тип, иначе он будет считать, что это обычный шаблон.

person David Rodríguez - dribeas    schedule 01.05.2012
comment
Согласитесь, что об этом слишком часто спрашивают. Компиляторы действительно должны предложить это (Вы имели в виду vector<typename vector<T>::iterator> ?). - person MSalters; 01.05.2012
comment
@MSalters GCC 4.6 делает это за меня - person Stephan Dollberg; 01.05.2012