Downcasting `vector<Parent>` - c++

I have a problem with upcasting and downcasting in my program. I have a vector<Child> that is passed to a function that expects const vector<Parent>& pp. There are no problems up to here (EDIT: apparently there are! See the comments). But, now I want to pass pp to a function that expects const vector<Child>& cc, Which I cannot do.
How should I do this, while at the same time I do not give the functions the ability to modify the original classes? Could you list various ways of doing this, preferably with their pros and cons?

There is a thing called variation. It comes in a 3 flavors:
invariation - even though B extends A, T<B> not extends T<A>,
covariation - when B extends A, then T<B> extends T<A>,
contravariation - when B extends A, then T<A> extends T<B>.
When it comes to C++ templates you end up with invariation. Even though by name it looks the same: vector<Parent> and vector<Child> those are 2 different types.
If you look at what is generated by compiler both of them operate on types which could potentially have different sizes. Since C++ rely on knowledge on object size (e.g. when it calculates position of object in an array) type e.g. Child[] cannot be casted to Parent[] because position of some object might be miscalculated. For the same reasons templates act in an invariant way: compiler cannot guess when it would and when it wouldn't be safe to perform such casting.
So it is up to you fix that and you have some options here. One would be making function that take that parameter template as well:
template<T>
void performAction(vector<T> objects) {
// ...
}
Other would be replacing values with a (smart) pointers - they would handle polymorphism easily.
EDIT:
To specify what I meant in the last sentence: you could simply use vector< unique_ptr<Parent> > or vector< shared_ptr<Parent> > to store any instance of Parent (including Child), so you won't have to perform any casting of the container.

Even if Child is derived from Parent or the other way round, vector<Child> and vector<Parent> are unrelated, they are different types.

You can have a template function template func(vector vec) { //do something based on the type of object passed }. Vectors are containers for objects so for a function which is expecting a vector &pp, if we pass vector && cc will not work and the code won't even compile.
We can use a code similar to:
class A
{
int i;
};
class B : public A
{
int j;
int k;
};
template<class T> void f(vector<T> &p)
{
//can handle both types now
}
int main()
{
B b1;
A a1;
vector<A> vectorA;
vectorA.push_back(a1);
vector<B> vectorB;
vectorB.push_back(b1);
f<B>(vectorB);
f<A>(vectorA);
return 0;
}

You can't. It's impossible.
Definitely don't do this:
template<typename TBase, typename TChild>
const std::vector<TBase*>& downcast(const std::vector<TChild*>& children)
{
static_assert(std::derived_from<TChild, TBase>);
return *reinterpret_cast<const std::vector<TBase*>*>(&children);
}

Related

How to pass a container of derived type to a function needing a container of base type [duplicate]

Consider these classes.
class Base
{
...
};
class Derived : public Base
{
...
};
this function
void BaseFoo( std::vector<Base*>vec )
{
...
}
And finally my vector
std::vector<Derived*>derived;
I want to pass derived to function BaseFoo, but the compiler doesn't let me. How do I solve this, without copying the whole vector to a std::vector<Base*>?
vector<Base*> and vector<Derived*> are unrelated types, so you can't do this. This is explained in the C++ FAQ here.
You need to change your variable from a vector<Derived*> to a vector<Base*> and insert Derived objects into it.
Also, to avoid copying the vector unnecessarily, you should pass it by const-reference, not by value:
void BaseFoo( const std::vector<Base*>& vec )
{
...
}
Finally, to avoid memory leaks, and make your code exception-safe, consider using a container designed to handle heap-allocated objects, e.g:
#include <boost/ptr_container/ptr_vector.hpp>
boost::ptr_vector<Base> vec;
Alternatively, change the vector to hold a smart pointer instead of using raw pointers:
#include <memory>
std::vector< std::shared_ptr<Base*> > vec;
or
#include <boost/shared_ptr.hpp>
std::vector< boost::shared_ptr<Base*> > vec;
In each case, you would need to modify your BaseFoo function accordingly.
Instead of passing the container object (vector<>), pass in begin and end iterators like the rest of the STL algorithms. The function that receives them will be templated, and it won't matter if you pass in Derived* or Base*.
This problem occurs in programming languages that have mutable containers. You cannot pass around a mutable bag of apples as a bag of fruit because you cannot be sure that someone else does not put a lemon into that bag of fruit, after which it no longer qualifies as a bag of apples. If the bag of apples were not mutable, passing it around as a bag of fruit would be fine. Search for covariance/contravariance.
one option is to use a template
template<typename T>
void BaseFoo( const std::vector<T*>& vec)
{
...
}
The drawback is that the implementation has to be in the header and you will get a little code bloat. You will wind up with different functions being instantiated for each type, but the code stays the same. Depending on the use case it's a quick and dirty solution.
Edit, I should note the reason we need a template here is because we are trying to write the same code for unrelated types as noted by several other posters. Templates allow you do solve these exact problems. I also updated it to use a const reference. You should also pass "heavy" objects like a vector by const reference when you don't need a copy, which is basically always.
Generally you would start with a container of base pointers, not the other way.
If you dealing with a third-party library, and this is your only hope, then you can do this:
BaseFoo (*reinterpret_cast<std::vector<Base *> *>(&derived));
Otherwise fix your code with one of the other suggesstions.
Taking Matt Price's answer from above, given that you know in advance what types you want to use with your function, you can declare the function template in the header file, and then add explicit instantiations for those types:
// BaseFoo.h
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
// BaseFoo.cpp
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
{
...
}
// Explicit instantiation means no need for definition in the header file.
template void BaseFoo<Base> ( const std::vector<Base*>& vec );
template void BaseFoo<Derived> ( const std::vector<Derived*>& vec );
If std::vector supported what you're asking for, then it would be possible to defeat the C++ type system without using any casts (edit: ChrisN's link to the C++ FAQ Lite talks about the same issue):
class Base {};
class Derived1 : public Base {};
class Derived2 : public Base {};
void pushStuff(std::vector<Base*>& vec) {
vec.push_back(new Derived2);
vec.push_back(new Base);
}
...
std::vector<Derived1*> vec;
pushStuff(vec); // Not legal
// Now vec contains a Derived2 and a Base!
Since your BaseFoo() function takes the vector by value, it cannot modify the original vector that you passed in, so what I wrote would not be possible. But if it takes a non-const reference and you use reinterpret_cast<std::vector<Base*>&>() to pass your std::vector<Derived*>, you might not get the result that you want, and your program might crash.
Java arrays support covariant subtyping, and this requires Java to do a runtime type check every time you store a value in an array. This too is undesirable.
They are unrelated types -- you can't.

C++ One std::vector containing template class of multiple types

I need to store multiple types of a template class in a single vector.
Eg, for:
template <typename T>
class templateClass{
bool someFunction();
};
I need one vector that will store all of:
templateClass<int> t1;
templateClass<char> t2;
templateClass<std::string> t3;
etc
As far as I know this is not possible, if it is could someone say how?
If it isn't possible could someone explain how to make the following work?
As a work around I tried to use a base, non template class and inherit the template class from it.
class templateInterface{
virtual bool someFunction() = 0;
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction();
};
I then created a vector to store the base "templateInterface" class:
std::vector<templateInterface> v;
templateClass<int> t;
v.push_back(t);
This produced the following error:
error: cannot allocate an object of abstract type 'templateInterface'
note: because the following virtual functions are pure within 'templateInterface'
note: virtual bool templateInterface::someFunction()
To fix this error I made the function in templateInterface not a pure virtual by providing a function body, this compiled but when calling the function the overide is not used, but instead the body in the virtual function.
Eg:
class templateInterface{
virtual bool someFunction() {return true;}
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction() {return false;}
};
std::vector<templateInterface> v;
templateClass<int> i;
v.push_back(i);
v[0].someFunction(); //This returns true, and does not use the code in the 'templateClass' function body
Is there any way to fix this so that the overridden function is used, or is there another workaround to store multiple template types in a single vector?
Why your code doesn't work:
Calling a virtual function on a value doesn't use polymorphism. It calls the function which is defined for the type of this exact symbol as seen by the compiler, not the runtime type. When you insert sub types into a vector of the base type, your values will be converted into the base type ("type slicing"), which is not what you want. Calling functions on them will now call the function as defined for the base type, since not it is of that type.
How to fix this?
The same problem can be reproduced with this code snippet:
templateInterface x = templateClass<int>(); // Type slicing takes place!
x.someFunction(); // -> templateInterface::someFunction() is called!
Polymorphism only works on a pointer or reference type. It will then use the runtime type of the object behind the pointer / reference to decide which implementation to call (by using it's vtable).
Converting pointers is totally "safe" with regard to type slicing. Your actual values won't be converted at all and polymorphism will work as expected.
Example, analogous to the code snippet above:
templateInterface *x = new templateClass<int>(); // No type slicing takes place
x->someFunction(); // -> templateClass<int>::someFunction() is called!
delete x; // Don't forget to destroy your objects.
What about vectors?
So you have to adopt these changes in your code. You can simply store pointers to actual types in the vector, instead of storing the values directly.
When working with pointers you also have to care about deleting your allocated objects. For this you can use smart pointers which care about deletion automatically. unique_ptr is one such smart pointer type. It deletes the pointee whenever it goes out of scope ("unique ownership" - the scope being the owner). Assuming the lifetime of your objects is bound to the scope this is what you should use:
std::vector<std::unique_ptr<templateInterface>> v;
templateClass<int> *i = new templateClass<int>(); // create new object
v.push_back(std::unique_ptr<templateInterface>(i)); // put it in the vector
v.emplace_back(new templateClass<int>()); // "direct" alternative
Then, call a virtual function on one of these elements with the following syntax:
v[0]->someFunction();
Make sure you make all functions virtual which should be possible to be overridden by subclasses. Otherwise their overridden version will not be called. But since you already introduced an "interface", I'm sure you are working with abstract functions.
Alternative approaches:
Alternative ways to do what you want is to use a variant type in the vector. There are some implementations of variant types, the Boost.Variant being a very popular one. This approach is especially nice if you don't have a type hierarchy (for example when you store primitive types). You would then use a vector type like std::vector<boost::variant<int, char, bool>>
Polymorphism only works through pointers or references. You'll
need the non-template base. Beyond that, you'll need to decide
where the actual objects in container will live. If they're all
static objects (with sufficient lifetime), just using
a std::vector<TemplateInterface*>, and inserting with
v.push_back(&t1);, etc., should do the trick. Otherwise,
you'll probably want to support cloning, and keep clones in the
vector: preferably with Boost pointer containers, but
std::shared_ptr can be used as well.
The solutions given so far are fine though be aware that in case you were returning the template type other than bool in your example , none of these would help as the vtable slots would not be able to be measured before hand. There are actually limits , from a design point of view , for using a template oriented polymorphic solution.
Solution nr. 1
This solution inspired by Sean Parent's C++ Seasoning talk. I highly recommend to check it out on youtube. My solution simplified a bit and the key is to store object in method itself.
One method only
Create a class that will invoke method of stored object.
struct object {
template <class T>
object(T t)
: someFunction([t = std::move(t)]() { return t.someFunction(); })
{ }
std::function<bool()> someFunction;
};
Then use it like this
std::vector<object> v;
// Add classes that has 'bool someFunction()' method
v.emplace_back(someClass());
v.emplace_back(someOtherClass());
// Test our vector
for (auto& x : v)
std::cout << x.someFunction() << std::endl;
Several methods
For several methods use shared pointer to share object between methods
struct object {
template <class T>
object(T&& t) {
auto ptr = std::make_shared<std::remove_reference_t<T>>(std::forward<T>(t));
someFunction = [ptr]() { return ptr->someFunction(); };
someOtherFunction = [ptr](int x) { ptr->someOtherFunction(x); };
}
std::function<bool()> someFunction;
std::function<void(int)> someOtherFunction;
};
Other types
Primitive types (such as int, float, const char*) or classes (std::string etc.) may be wrapped in the same way as object class do but behave differently. For example:
struct otherType {
template <class T>
otherType(T t)
: someFunction([t = std::move(t)]() {
// Return something different
return true;
})
{ }
std::function<bool()> someFunction;
};
So now it is possible to add types that does not have someFunction method.
v.emplace_back(otherType(17)); // Adding an int
v.emplace_back(otherType("test")); // A string
Solution nr. 2
After some thoughts what we basically done in first solution is created array of callable functions. So why not just do the following instead.
// Example class with method we want to put in array
struct myclass {
void draw() const {
std::cout << "myclass" << std::endl;
}
};
// All other type's behaviour
template <class T>
void draw(const T& x) {
std::cout << typeid(T).name() << ": " << x << std::endl;
}
int main()
{
myclass x;
int y = 17;
std::vector<std::function<void()>> v;
v.emplace_back(std::bind(&myclass::draw, &x));
v.emplace_back(std::bind(draw<int>, y));
for (auto& fn : v)
fn();
}
Conclusion
Solution nr. 1 is definitely an interesting method that does not require inheritance nor virtual functions. And can be used to other stuff where you need to store a template argument to be used later.
Solution nr. 2, on the other hand, is simpler, more flexible and probably a better choice here.
If you're looking at a container to store multiple types, then you should explore boost variant from the popular boost library.

C++: treating structure members as an array

I have a structure containing lots (like, hundreds) of pointers. Each pointer is a different type, but they all inherit from a common base class --- let's call it Base. I'm using multiple inheritance. (This is all machine-generated, which is why it's weird.)
e.g.:
class Data {
Class1* p1;
Class2* p2;
Class3* p3;
...etc...
};
I want to call a method defined in Base on all of these. I can generate code like this:
void callFooOnData(Data* p)
{
if (p1) p1->Foo();
if (p2) p2->Foo();
if (p3) p3->Foo();
...etc...
}
The problem is, I've got lots and lots of these, of a billion different kinds of Data, and the above code ends up being very large and is affecting my footprint. So I'm trying to replace this with something smarter.
In C, I could simply take the address of the first structure member and the count, and do something like:
void callFooOnData(Data* p)
{
callFooOnObjects(&p1, 3);
}
But, of course, I can't do this in C++, because the structure members aren't a uniform type, and casting them to Base* may involve changing them, and this may involve changing the pointer, and because they're not a uniform type the pointers will have to be changed differently for each member, and I can't do that.
Is there a way to do something like this is C++? This is all machine generated code, so it doesn't have to be pretty, thankfully --- that shark has already been jumped --- but I do need it to be as portable as possible...
(I do have access to RTTI, but would like to avoid it if possible for performance reasons.)
Update:
So, as far as I can tell... you just can't do this in C++. Simply can't be done. I was misled by the fact that it's totally straightforward in C. In C++ you can only safely cast a pointer between two types in a class hierarchy if you have a well typed pointer to begin with, and of course, I don't.
So I'm going to have to change the underlying problem to avoid this: the solution I've come up with is to store every pointer in the structure twice, once in an array of Base* for iterating over, and once as a ClassWhatever* for calling methods on. Which sucks, of course, because it's going to double the size of the Data structure.
So if anyone would like to confirm this (I would love to be proven wrong), I will happily mark their answer as correct...
Each pointer is a different type, but they all inherit from a common base class --- let's call it Base
Instead of having hundreds of members, just keep a container of Base class pointers:
class Data {
std::vector<Base*> objects;
};
In a good design, you don't really need to know the type of each object, and it's actually better if it's abstracted away. Remember, it's always good to program against interfaces, not concrete classes.
and casting them to Base* may involve changing them
Not really, for public inheritance the cast should be implicit.
If you only call Foo() on all of them, Foo() can be a virtual method in the base class, that way you take full advantage of polymorphism.
But, of course, I can't do this in C++, because the structure members
aren't a uniform type, and casting them to Base* may involve changing
them, and this may involve changing the pointer, and because they're
not a uniform type the pointers will have to be changed differently
for each member, and I can't do that.
Although its a bad idea, this is not true:
you can iterate over the pointers using pointer arithmetic like you do in C. The pointers are all the same size, and they have a common base class (not considering structure alignment problems etc). Its dirty but technically it works. That would be different if you hold the instances themselves as members in the class, not pointers to them.
The best way in C++11 would be to use
std::vector< std::unique_ptr<Base> > objects;
see http://www.drdobbs.com/cpp/c11-uniqueptr/240002708
You must "fight" with auto-generated code by auto-generating your code too. You can use tools like ctags to "parse" your auto-generated classes and auto-generate your code from ctags output. See http://ctags.sourceforge.net/ctags.html.
You can also try to cast your Data to tuple as advised in this, possible duplicate, question: Iterate through struct variables.
I am not sure which is faster...
If you can modify tool which auto-generates this source code - maybe best would be to extend this tool...
Another option (not compileable):
class DataManipulator
{
public:
DataManipulator(const Data& aData_in)
{
objects.add(aData_in->Class1);
.
.
}
void operate()
{
for(objects_iterator...)
{
if(*objects_iterator != NULL)
objects_iterator->Foo();
}
}
private:
std::vector<Base*> objects;
};
I did not want to change my previous answer. However I come to another solutions which should work for you: full example here: http://ideone.com/u22FO
The main part below:
struct C {
A1* p1;
A2* p2;
A3* p3;
A4* p4;
// ...
};
template <class D, size_t startNumber, size_t numMembers, bool notFinished>
struct FooCaller;
template <class D, size_t startNumber>
struct FooSingleCall;
template <class D, size_t startNumber, size_t numMembers>
struct FooCaller<D, startNumber, numMembers, false> {
void operator() (D& d) {}
};
template <class D, size_t startNumber, size_t numMembers>
struct FooCaller<D, startNumber, numMembers, true> {
void operator() (D& d) {
FooSingleCall<D,startNumber>()(d);
FooCaller<D, startNumber + 1, numMembers, startNumber < numMembers>()(d);
}
};
#define FooSingleCallD(n) \
template <class D> \
struct FooSingleCall<D,n>{ \
void operator() (D& d) { \
d.p##n->foo(); \
} \
}
FooSingleCallD(1);
FooSingleCallD(2);
FooSingleCallD(3);
FooSingleCallD(4);
// ... unfortunately repeat as many times as needed
template <class D, size_t numMembers>
void callFoo(D& d)
{
FooCaller<D, 1, numMembers, 1 <= numMembers>()(d);
}
Aware: be smart enough not to define hundreds of FooSingleCall... See one of the answers to this famous question: https://stackoverflow.com/a/4581720/1463922 and you will see how to make 1000 instances in just 5 lines...
Also, please replace FooSingleCall with something retrieving N-pointer from your class - something like GetNPointer...
All the pointers are the same size (all class object pointers in C++ are the same size), and in practice the compiler needs to be rather perverse in order to insert padding anywhere in this list of pointers. Anyway, the problem of possible padding is the same as in C. So you can do just the same as in C, no problem at all.
void foo( Base const* );
void bar()
{
// ...
foo( *(&thingy.p1 + 3) );
}
It's that easy.
That said, even with machine generated code the design sounds horrible, wrong, really really bad.
One does got something of that sort when generating vtables (where each pointer is to a function of generally different signature), but it's very rare. So, this sounds like an XY problem. Like, you’re trying to solve problem X, have come up with an ungood solution Y, and are now asking about imagined solution Y instead of the real problem X…

Passing void(*) in C++

I have a std::map which I'm trying to store void pointers for the values. The problem is, most of the pointer I'm trying to store are methods in a class and have different amount of params. I know for the params I can use a va list so thats not too much of a problem, the problem would be the actual pointer itself.
This is what I have:
class A
{
public:
A();
void methodA(...);
};
class B
{
public:
B();
void methodB(...);
};
void method_no_class(...) { }
std::map<int, void(*)(...)> my_map;
my_map[0] = &method_no_class;
B* cb = new B();
my_map[1] = &cb->methodB; // will return error
Maybe this information my help you:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
Pointer to method is of different type than pointer to function. If you want to store them both in single collection you have to do manual casts.
The clean OO way would be to define a command interface. The interface would take an instance (of A or B) and all parameters. In the invoke() method, it would call the method of the instance.
You could then use a map of these command interfaces (just define a common subclass for them which defines the abstract invoke() method). The compiler would check all types and arguments for you, and you wouldn't have to use varargs.
Following up on Kamil Szot's answer, the C++ FAQ (and the book) is an excellent reference to the murky depths of C++ and object oriented programming in general. Section 33 addresses specifically the problem you are having:
In C++, member functions have an implicit parameter which points to the object (the this pointer inside the member function). Normal C functions can be thought of as having a different calling convention from member functions, so the types of their pointers (pointer-to-member-function vs. pointer-to-function) are different and incompatible.
Of course, the answer to your question is somewhat lacking in details.
You might want to look at method operaters ->, ::, and their friends. I'll try to find a better link but start here.
UPDATE: hopefully this is a better article for method pointers and operators.
You should functionoids here. They can be used as a flexible and type safe replacement for function pointers with different signatures. A abstract base class is needed. It contains the actual function invocation with the common parameters, if there are any.
class Functioniod: public YourClass {
virtual void execute(char d, common_parameters,...) = 0
}
For every function you want to use, you create a derived class. The constructor contains the function-specific parameters, and the execute() function the actual call. This execute function is later called instead of the function pointer. It needs to have the same signature in every functionoid. It could call something different in any other class too, of course.
class FuncA: public Functionoid {
FuncA(int _a, float _b, string _c, function-specific-parameters...) {
a = _a; b = _b; c = _c;
}
void execute(char d, common-parameters,...) {
call-to-member(d, a, b, c);
}
int a;
float b;
string c;
}
Now if you want to use this as a replacement for your member function pointer, you would do:
std::map<int, *Functionoid> my_map;
my_map[0] = new FuncA(someInt, someFloat, someString);
my_map[1] = new FuncB(some-other-parameters...);
and execute them with
my_map[0]->execute(common-parm);
my_map[1]->execute(common-parm);
Here's an example code to get you started. Haven't compiled it, so might require some tuning.
#define func(Instance,Method,Class) \
(__int64(Instance)<<32 + __int64(&Class::Method))
#define invoke(Func,Method,Class) \
invoke1(Func,(Class*)0)->*invoke2(Func,&Class::Method)
template<class Class>
Class* invoke1(__int64 Func,Class*)
{
return (Class*)(int)(Func>>32);
}
template<class Method>
Method invoke2(__int64 Func,Method)
{
return (Method)(int)Func;
}
------------ USAGE ------------
class B
{
void methodB(int a,float b){}
};
std::map<int, __int64> my_map;
my_map[0] = func(cb,methodB,B);
invoke(my_map[0],methodB,B)(1,2.f);

Getting a vector<Derived*> into a function that expects a vector<Base*>

Consider these classes.
class Base
{
...
};
class Derived : public Base
{
...
};
this function
void BaseFoo( std::vector<Base*>vec )
{
...
}
And finally my vector
std::vector<Derived*>derived;
I want to pass derived to function BaseFoo, but the compiler doesn't let me. How do I solve this, without copying the whole vector to a std::vector<Base*>?
vector<Base*> and vector<Derived*> are unrelated types, so you can't do this. This is explained in the C++ FAQ here.
You need to change your variable from a vector<Derived*> to a vector<Base*> and insert Derived objects into it.
Also, to avoid copying the vector unnecessarily, you should pass it by const-reference, not by value:
void BaseFoo( const std::vector<Base*>& vec )
{
...
}
Finally, to avoid memory leaks, and make your code exception-safe, consider using a container designed to handle heap-allocated objects, e.g:
#include <boost/ptr_container/ptr_vector.hpp>
boost::ptr_vector<Base> vec;
Alternatively, change the vector to hold a smart pointer instead of using raw pointers:
#include <memory>
std::vector< std::shared_ptr<Base*> > vec;
or
#include <boost/shared_ptr.hpp>
std::vector< boost::shared_ptr<Base*> > vec;
In each case, you would need to modify your BaseFoo function accordingly.
Instead of passing the container object (vector<>), pass in begin and end iterators like the rest of the STL algorithms. The function that receives them will be templated, and it won't matter if you pass in Derived* or Base*.
This problem occurs in programming languages that have mutable containers. You cannot pass around a mutable bag of apples as a bag of fruit because you cannot be sure that someone else does not put a lemon into that bag of fruit, after which it no longer qualifies as a bag of apples. If the bag of apples were not mutable, passing it around as a bag of fruit would be fine. Search for covariance/contravariance.
one option is to use a template
template<typename T>
void BaseFoo( const std::vector<T*>& vec)
{
...
}
The drawback is that the implementation has to be in the header and you will get a little code bloat. You will wind up with different functions being instantiated for each type, but the code stays the same. Depending on the use case it's a quick and dirty solution.
Edit, I should note the reason we need a template here is because we are trying to write the same code for unrelated types as noted by several other posters. Templates allow you do solve these exact problems. I also updated it to use a const reference. You should also pass "heavy" objects like a vector by const reference when you don't need a copy, which is basically always.
Generally you would start with a container of base pointers, not the other way.
If you dealing with a third-party library, and this is your only hope, then you can do this:
BaseFoo (*reinterpret_cast<std::vector<Base *> *>(&derived));
Otherwise fix your code with one of the other suggesstions.
Taking Matt Price's answer from above, given that you know in advance what types you want to use with your function, you can declare the function template in the header file, and then add explicit instantiations for those types:
// BaseFoo.h
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
// BaseFoo.cpp
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
{
...
}
// Explicit instantiation means no need for definition in the header file.
template void BaseFoo<Base> ( const std::vector<Base*>& vec );
template void BaseFoo<Derived> ( const std::vector<Derived*>& vec );
If std::vector supported what you're asking for, then it would be possible to defeat the C++ type system without using any casts (edit: ChrisN's link to the C++ FAQ Lite talks about the same issue):
class Base {};
class Derived1 : public Base {};
class Derived2 : public Base {};
void pushStuff(std::vector<Base*>& vec) {
vec.push_back(new Derived2);
vec.push_back(new Base);
}
...
std::vector<Derived1*> vec;
pushStuff(vec); // Not legal
// Now vec contains a Derived2 and a Base!
Since your BaseFoo() function takes the vector by value, it cannot modify the original vector that you passed in, so what I wrote would not be possible. But if it takes a non-const reference and you use reinterpret_cast<std::vector<Base*>&>() to pass your std::vector<Derived*>, you might not get the result that you want, and your program might crash.
Java arrays support covariant subtyping, and this requires Java to do a runtime type check every time you store a value in an array. This too is undesirable.
They are unrelated types -- you can't.