Implicit conversion of the vector <shared_ptr <Foo>> to the vector <shared_ptr <const Foo >>
According to this page, you can implicitly convert shared_ptr<Foo> to shared_ptr<const Foo> . It makes sense.
However, I encounter an error when I try to convert std::vector containing shared_ptr<Foo> to one containing shared_ptr<const Foo> .
Is there a good way to achieve this conversion?
No: std::vector<shared_ptr<Foo> > and std::vector<shared_ptr<const Foo> > are different types, so you cannot consider an object as an object of another type.
If you really need std::vector<shared_ptr<const Foo> > , you can easily create it with shared_ptr with the same elements as the original:
std::vector<shared_ptr<Foo> > v; std::vector<shared_ptr<const Foo> > cv(v.begin(), v.end()); However, if you write your code in terms of iterators, you should not have any problems with this. That is, instead of using
void f(const std::vector<shared_ptr<const Foo> >&); // used as: std::vector<shared_ptr<const Foo> > v; f(v); you should use
template <typename ForwardIterator> void f(ForwardIterator first, ForwardIterator last); // used as: std::vector<shared_ptr<const Foo> > v; f(v.begin(), v.end()); Thus, the function f simply requires that it gets a number of things that can be used as pointers to const Foo (or shared_ptr<const Foo> s if the function assumes the range contains shared_ptr s).
When a function takes a range instead of a container, you separate the function from the underlying data: it doesn't matter what the actual data is and how it is stored, if you can use it the way you need to use it.
Why do you need std::vector<shared_ptr<Foo const> > ? conversion is easy; just use the two std::vector iterator constructor. But in many cases you donβt need it: as a rule, const-correctness is not related to dynamically distributed objects, and if you need shared_ptr<Foo const> , automatic conversion when extracting an object from a vector.