我想传递一个填充了基于同一类的对象的向量。
std::reference_wrapper
和无引用都无法解决问题。
解决这个问题的正确方法是什么?
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;
}
答案 0 :(得分:1)
{
MySubClass s(2);
std::vector<MyClass> v;
v.push_back(s);
test(v);//print MyClass, but I need MySubClass
}
此处的问题是您尝试将MySubClass
个对象存储在MyClass
的向量中。无法存储整个MySubClass
,而只存储MyClass
父子对象。这与您希望将存储对象视为MySubClass
个实例的愿望相冲突。
{
MySubClass s(2);
std::vector<std::reference_wrapper<MyClass>> v;
v.push_back(s);
这解决了以前的问题。引用可以引用其静态类型的子类。但是,请记住,对象不存储在向量中。该对象存储为局部变量s
,仅由向量引用。
test(v);//print MySubClass
test({2});
test({s});//wrong ambigious
这里的问题是你有两个重载,其中既没有接受MySubClass
,也接受可以从MySubClass
的初始化列表初始化的东西。因此,重载分辨率是不明确的。编译器不知道您打算调用哪个重载。
使用显式临时初始化而不是普通初始化列表。
test(std::vector<MyClass>{2});
test(std::vector<std::reference_wrapper<MyClass>>{s});
或者不要使用重载,而是使用唯一命名的函数。
void test(const std::vector<std::reference_wrapper<MyClass>>& v)
void test2(const std::vector<MyClass>& v)