I want to pass the a vector filled with object based same class.
Both std::reference_wrapper
and no-reference do not fix it.
What's the correct way to solve this?
class MyClass
{
public:
MyClass(int){};
virtual void print() const {
std::cout<<"MyClass"<<std::endl;
}
};
class MySubClass : public MyClass
{
public:
MySubClass(int a):MyClass(a){};
virtual void print() const {
std::cout<<"MySubClass"<<std::endl;
}
};
void test(const std::vector<std::reference_wrapper<MyClass>>& v)
{
for (const auto& c : v) {
c.get().print();
}
}
void test(const std::vector<MyClass>& v)
{
for (const auto& c : v) {
c.print();
}
}
int main()
{
{
MySubClass s(2);
std::vector<MyClass> v;
v.push_back(s);
test(v);//print MyClass, but I need MySubClass
}
{
MySubClass s(2);
std::vector<std::reference_wrapper<MyClass>> v;
v.push_back(s);
test(v);//print MySubClass
test({2});
test({s});//wrong ambigious
}
return 0;
}
The problem here is that you're attempting to store
MySubClass
objects in a vector ofMyClass
. It is not possible to store the entireMySubClass
, instead only theMyClass
parent subobject is stored. This conflicts with your desire to treat the stored objects as if they wereMySubClass
instances.This solves the previous problem. References can refer to a subclass of their static type. Although, keep in mind that the object is not stored in the vector. The object is stored as a local variable
s
and only referenced by the vector.The problem here is that you have two overloads, of which neither accept a
MySubClass
, but both accept something that can be initialized from an initialization list ofMySubClass
. Therefore the overload resolution is abiguous. The compiler doesn't know which overload you intended to call.Either use explicit temporary initialization instead of a plain initializion list.
Or don't use overloads, but uniquely named functions instead.