I have a function that takes, as an argument, an stl vector of pointers to Foo.
However, I also have objects which are shared pointers to the same class Foo. I would like to be able to call this function feeding this other objects too. Do I have to overload the function? I seem to be unable to dynamic-cast it from vector<shared_ptr<Foo>> to vector<Foo*>.
I know one can convert a shared_ptr to a pointer with the Get() method, but what about this? Any ideas?
Update on the question:
I have implemented the solution suggested below, but now, when declaring all the possible types for the template function, I get:
“explicit instantiation of ‘void my_func(std::vector&, std::vector&) [with Ptr_Jet1 = Jet*, Ptr_Jet2 = Jet*]’ but no definition available”
and the same thing for all the other combinations (for example, Ptr_Jet1 being shared_ptr instead of Jet*.
On the .cpp file, I have:
template<typename Ptr_Jet1, typename Ptr_Jet2>
void my_func(vector<Ptr_Jet1> vec1, vector<Ptr_Jet2> vec2){
//definition
}
and on the .h file, I have:
typedef boost::shared_ptr<Jet> ptr_jet;
template<typename Ptr_Jet1, typename Ptr_Jet2>
void my_func(vector<Ptr_Jet1> vec1, vector<Ptr_Jet2> vec2);
//
template void my_func(vector<Jet*> vec1, vector<Jet*> vec2);
template void my_func(vector<Jet*> vec1, vector<ptr_jet> vec2);
template void my_func(vector<ptr_jet> vec1, vector<Jet*> vec2);
template void my_func(vector<ptr_jet> vec1, vector<ptr_jet> vec2);
I don’t get what’s wrong here…
If you wrote that function, I would suggest templatization, as shared_ptr has
operator*just as you would use the raw pointers.In this situation, templatization does essentially the same as function overloading, but with templatization you avoid duplicating your code.
If you don’t have control over the function, you need to convert the whole vector. If it is not more than a 1000 elements and you don’t do it more than a couple hundred times, there’s not much performance loss to fear about.
Unfortunately you cannot dynamic cast the one to the other as they are not related through inheritance. Although they look alike,
vector<T>has nothing to do withvector<U>.UPDATE:
I agree with Grizzly, template arguments are automatically deduced so you don’t need to explicitly write that out. So you can keep calling it
your_fun(v).The only thing you need to be careful with: if you work with header and code files separately, you need to explicitly instruct the compiler that it should create both of your functions, like this:
UPDATE2: (answering Elelias’es comment)
Your template declaration should look like this:
After that, you have 2 options:
You can put the definition into a separate code file. In that case, you’ll need 6 explicit template instantiations in the implementation file for the header, one for each combination.
You can put the definition into the header and then you don’t need the 6 explicit instantiations. I would rather suggest this in this case. Although it does not separate declaration and implementation, it is not that bad solution. I have seen this approach in serious c++ libraries too, as an example you can have a look at operations.hpp in OpenCV.