1

I have two classes, obstacle and boid, boid inherits from obstacle.

Now I want to write some functions that can work with objects of both classes, so that passing vector<boid> does work as well as vector<obstacle>.

When I typecast like this and try to access the size of the vector I get a number of 1840700394 instead of 60:

vector<boid>* boids; ....
cout << ((vector<obstacle>*)boids)->size() << endl;

I also tryed "reinterpret_cast" but same problem.

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
Jan
  • 21
  • 2
  • 5
    Why are you using a `std::vector<>` __pointer__? This doesn't make sense for the piece of code you're showing and indicates that you're missing a lot about object lifetime in C++. You might need [a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – sbi Oct 30 '10 at 13:49

3 Answers3

7

C++ templates are not like C# and Java generics. A template instantiation is a complete class, and is not related to other template instantiations in any way whatsoever. One cannot cast between them.

(Side Note: If you were using static_cast instead it would have caught this for you....)

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
3

You can't cast a vector to a different type of vector like that. If you need a generic function that works with both types of objects, you can use a function template.

template <typename T>
void func(const std::vector<T>& vec)
{
  ....
}

This function will accept a vector containing any type of object.

Also, see Roger Pate's comment below. You can let the function accept any type of container (or any object that implements the appropriate semantics) by just saying:

template <typename T>
void func(const T& container) { ... }
Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • 4
    Better yet, make the entire container a template parameter. –  Oct 30 '10 at 13:43
  • 2
    Or pass a range instead of a container? – eq- Oct 30 '10 at 13:55
  • 1
    @eq-: Sometimes you really need the container; e.g. to call erase or other methods. –  Oct 30 '10 at 14:04
  • Without reading up all about "templates", i can imagine it is not possible to access members of the objects when using templates? – Jan Oct 30 '10 at 14:21
  • 2
    @Jan: It is possible to access members. In a nutshell, templates are just code generation performed by the compiler for you, so `template void f(T x) {}` gives you `void f(int x)`, `void f(char x)`, `void f(std::string x)`, ad infinitum. –  Oct 30 '10 at 14:24
3

A simple way to solve this kind of problem is to use a std::vector<obstacle *>. Then you can populate your vector with pointers to any object that inherits from obstacle.

Rémi
  • 3,705
  • 1
  • 28
  • 39
  • Don't do this; instead use a smart container of pointers (e.g. boost::ptr_vector) or a container of smart pointers. – Fred Nurk Dec 23 '10 at 23:53