error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'const std::vector<_Ty> &`
Solution 1
In the view of the C++ compiler, shared_ptr<BaseClass>
and shared_ptr<DerivedClass>
are different, unrelated types. While the compiler knows, that normal Pointers can be converted from Derived*
to Base*
, it does not know that conceptually the same should apply for shared_ptr
s, because it does not know "smart pointers" being pointer-like.
The same applies for vector or for templates in general: two instantiations of a template are two different class, with no relation betwen them (if not designed explicitly). So the compiler sees a vector<Something>
bound to a reference to a vector<SomethingElse>
which are not related types, so the reference binding fails.
But even if the types were somehow related, the binding would fail:
long l = 5;
int& ir = l; //ERROR
Solution 2
shared_ptr<BaseClass>
and shared_ptr<SubClass>
are distinct, unrelated types, so there's no way for a vector of one to alias a vector of the other, because there's no guarantee that their object layout is the same.
This means that to e.g. pass const std::vector<boost::shared_ptr<BaseClass> >&
to a function you'll have to construct a temporary vector of the desired type. You can however do this without incrementing the reference counts on the shared pointers, using shared pointer aliasing:
#include <vector>
#include <memory>
struct B {};
struct D: public B {};
template<typename T, typename U>
std::vector<std::shared_ptr<T>> shared_vector_static_cast(
const std::vector<std::shared_ptr<U>> &v)
{
std::vector<std::shared_ptr<T>> w;
for (const std::shared_ptr<U> &p: v)
w.push_back(std::shared_ptr<T>(std::shared_ptr<void>(), p.get()));
return w;
}
int main() {
std::vector<std::shared_ptr<D>> v{std::make_shared<D>()};
const std::vector<std::shared_ptr<B>> &w = shared_vector_static_cast<B>(v);
}
Related videos on Youtube
q0987
Updated on July 17, 2022Comments
-
q0987 almost 2 years
Question1> Why the following code doesn't work?
Question2> What is the correct way to design it?
#include <iostream> #include <vector> #include "boost/shared_ptr.hpp" using namespace std; class BaseClass {}; class SubClass : public BaseClass {}; int main() { std::vector<boost::shared_ptr<SubClass> > vecSubClassShared; boost::shared_ptr<SubClass> sub1(new SubClass); vecSubClassShared.push_back(sub1); // Error 1 error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'const std::vector<_Ty> &` const std::vector<boost::shared_ptr<BaseClass> >& vecBaseShared = vecSubClassShared; }
-
q0987 about 11 yearsThere is a bug in the code. The size of w is the end is 2*v.size() rather than v.size().