15

I have a problem about how to use iterator under the template manner.
Here is an example I am trying to do, the problem is that, inside the for loop how can I initial the iterator pp ?

I have read a similar question, but I cannot fully understand that since I am a beginner.
What should the iterator type be in this C++ template?
Can anyone help and also provide some simple explanation?

#include <iostream>
#include <vector>

template <class T>
void my_print(std::vector<T> input){
    for(std::vector<T>::iterator pp = input.begin(); pp != input.end(); ++pp)
        std::cout << *pp << "\n";
}
int main(int argc,char* argv[]){
    std::vector<int> aa(10,9);
    my_print(aa);

    return 0;
}

error message I got:
‘std::vector::iterator’ is parsed as a non-type, but instantiation yields a type

Community
  • 1
  • 1
sflee
  • 1,659
  • 5
  • 32
  • 63
  • 2
    Having a nicer compiler: error: need ‘typename’ before ‘std::vector::iterator’ because ‘std::vector’ is a dependent scope –  Jan 01 '14 at 08:44
  • 1
    Also, to avoid a costly copy, you should change to `my_print(std::vector const &input)` and `const_iterator`. – Christopher Creutzig Jan 01 '14 at 09:01
  • With C++11, you may write `for (const auto& elem : input) { std::cout << elem << "\n"; }`. – Jarod42 Jan 01 '14 at 10:31

2 Answers2

26

Add a typename before the iterator

#include <iostream>
#include <vector>

template <class T>
void my_print(std::vector<T> input)
{
    for (typename std::vector<T>::iterator pp = input.begin(); pp != input.end(); ++pp)
    {
        std::cout << *pp << "\n";
    }
}
int main(int argc, char* argv[])
{
    std::vector<int> aa(10, 9);
    my_print(aa);

    return 0;
}

source: http://www.daniweb.com/software-development/cpp/threads/187603/template-function-vector-iterator-wont-compile

MoonBun
  • 4,322
  • 3
  • 37
  • 69
  • 2
    Can you explain why `typename` is necessary? What is the intuition behind it? Is it recommended to use `typename` or `class`? – Gilfoyle Nov 12 '19 at 12:35
4

Like Dieter says, newer versions of gcc will pretty much tell you where typename is needed:

error: need 'typename' before 'std::vector<T>::iterator' 
       because 'std::vector<T>' is a dependent scope

Simple fix:

for(typename std::vector<T>::iterator pp = input.begin(); 
          pp != input.end(); ++pp)

Here is an explanation Error with T::iterator, where template parameter T might be vector<int> or list<int>

Before a qualified dependent type, you need typename. Without typename, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error.

For a more comprehensive explanation, check out Why is the keyword "typename" needed before qualified dependent names, and not before qualified independent names?

Community
  • 1
  • 1