1

I'm trying to encapsulate the C++ Standard Library's vector class using templates but I keep getting the error

SceneVector.h: In member function ‘void scenegraph::SceneVector<V>::print()’:
SceneVector.h:40: error: expected ‘;’ before ‘it’
SceneVector.h:40: error: ‘it’ was not declared in this scope

The code I've managed to create is

#include <map>
#include <vector>
#include <iostream>

namespace scenegraph
{
    template <class V> class SceneVector
    {
        typedef std::vector<V> Vector;
        Vector vector;

        public:
            SceneVector();
            void insert(const V value);
            void print();
    };

    template <class V> SceneVector<V>::SceneVector()
    {
        vector.clear();
    }

    template <class V> void SceneVector<V>::insert(const V value)
    {
        vector.push_back(value);
    }

        template <class V> void SceneVector<V>::print()
    {
        for(Vector::iterator it = vector.begin(); it != vector.end(); ++it)
        {
            std::cout << "[" << (*it) << "] " << std::endl;
        }
        std::cout << std::endl;
    }
}

Can anyone correct me here? I must reinforce I'm a C++ newbie so the answer may be extremely trivial.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jorge Silva
  • 15
  • 1
  • 5

2 Answers2

3

When accessing types that depend on a template parameter, you must prepend typename to make clear to the parser that the type is a type.

for(typename Vector::iterator it = vector.begin(); it != vector.end(); ++it)

It is possible for Vector::iterator to be a compile-time constant number, and the compiler can't know that until instantiation time. That's why you have to tell it explicitely.

thiton
  • 35,651
  • 4
  • 70
  • 100
  • You are correct. By the way what I'm trying to achieve here is a data structure that will allow me to have a insertion ordered map. I use a vector for maintaining insertion order and a map to maintain key to value relation. Am I on the right track? – Jorge Silva Nov 13 '11 at 18:21
  • 1
    @JorgeSilva: You could just use Boost.MultiIndex. – thiton Nov 13 '11 at 18:26
  • @JorgeSilva: What's a "scholar project" -- do you mean "homework"? It's generally a good idea to indicate in your question whether you're after a serious answer, or whether you're trying to solve some artificial puzzle. – Kerrek SB Nov 13 '11 at 18:52
  • @kerrek-sb as a "scholar project" I meant a project I'm doing for school as part of a midterm assignment. In the process of doing the the assignment I'm also taking the chance to learn myself some new things so I'm always after a serious answer. I do not see this as an "artificial puzzle". Nevertheless, the next question I pose related to a school assignment I will explicitly name it as such. – Jorge Silva Nov 13 '11 at 19:40
  • @JorgeSilva: I'd say anything that imposes artificial restrictions is somewhat contrived. Say you needed to write a dictionary. The puzzle might be how to design a hash table, but if it were real code, the only sensible advice is to use a high-quality library component like `unordered_map`. It really all depends on what you're trying to get out of the programming activity, so it's helpful if you state that. Anyway, good luck! – Kerrek SB Nov 13 '11 at 19:42
3

If you had a plain

std::vector<V>::iterator

it would be pretty obvious that it is dependent name, and that you need a typename to indicate that iterator is a type.

Using a typedef doesn't really change that.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203