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
MySubClassobjects in a vector ofMyClass. It is not possible to store the entireMySubClass, instead only theMyClassparent subobject is stored. This conflicts with your desire to treat the stored objects as if they wereMySubClassinstances.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
sand 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.