views:

390

answers:

2

The following code excerpt is responsible for a cryptic MSVC++ compiler error:

template<class T> class Vec : public vector<T>{
  public:
    Vec() : vector<T>(){}
    Vec(int s) : vector<T>(s){}

    T& operator[](int i){return at(i);  }
    const T& operator[](int i)const{ return at(i);}
};

...

The error:

test.cpp(5) : error C2143: syntax error : missing ',' before '<'
  test.cpp(12) : see reference to class template instantiation 'Vec<T>' being compiled

How do I fix this?

---Edit---

Some context:

I am trying to compile code essentially copy and pasted from The C++ Programming Language. I don't yet even understand this code completely. The purpose, however, is to implement a vector type that will throw an exception when some code attempts to access an item out of the vector's range instead of just returning incorrect values.

+1  A: 

Why are you attempting to inherit from vector? This will cause you a lot of problems. The least of which is that vector does not have a virtual destructor. This will cause the wrong destructor to be called when deleting a polymorphic reference to your class which will lead to memory leaks or general bad behavior.

For instance, the following code will not call ~Vec() but will call ~vector() instead.

vector<int> *pVec = new Vec<int>();
delete pVec;  // Calls ~vector<T>();

The actual compile error you are seeing though is because you're using the template syntax for the base constructor call. Simply remove that and it should compile

Vec() : vector() {}
JaredPar
+1. You're right to warn about non-polymorphic deletion, but OTOH, any code that dynamically allocates vectors is suspicious anyway. (The only reason I can think of for dynamically allocating something is when you don't know its size until runtime -- but a vector's size can vary at runtime anyway.)
j_random_hacker
The main reason for dynamically allocating something is of you don't know how many of the items you have until runtime, or what their actual types will be.
anon
@Neil: Good point in general, but in the specific case of vectors: (1) Re not knowing how many: it's safer to use a vector of vectors than dynamically allocating an array of vectors with new; (2) Re not knowing actual types: not knowing the exact type of vector you want smells like overdesign to me.
j_random_hacker
+3  A: 

Try

template<class T> class Vec : public vector<T>{
  public:
    Vec() : vector(){} // no <T>
    Vec(int s) : vector(s){} // same

    T& operator[](int i){return at(i);  }
    const T& operator[](int i)const{ return at(i);}
};

The constructor for a template class does not include the template signature in its name.

As a side note, your second constructor should really be

Vec(typename vector<T>::size_type s) : vector(s){} // not necessarily int

Finally, you really shouldn't derive from vector, as it has a non-virtual destructor. Do not attempt to delete a Vec through a pointer to a vector.

rlbond
Actually, the second constructor should be Vec(size_type s). It's the number of elements in the vector, not an element to be put into the vector.
Fred Larson
size_type >> size_t
Benoît
@Benoît: Not necessarily. std::vector defines size_type, which may or may not be the same as size_t.
Fred Larson