#include <iostream>
#include <vector>
using namespace std;
class Base {
public:
virtual ~Base(){}
};
class Deriv : public Base {
public:
virtual ~Deriv(){}
};
void f(Base *){
cout << "f(Base *)" << endl;
}
void f(vector<Base *>){
cout << "f(vector<Base *>)" << endl;
}
int main(int argc, const char *argv[])
{
Deriv *d = new Deriv;
vector<Deriv *> v;
v.push_back(d);
f(d); // works
//f(v); // does not compile
return 0;
}
第一个f()有效,但第二个给出编译时错误:
f(vector<Deriv *>) not found.
我的问题:有没有办法让它工作:某种带向量的多态性?
答案 0 :(得分:4)
您想要的属性称为协方差。答案是否定的,你不能这样做:向量不是协变的。
为什么不允许这样做的典型例子是这样的:
class Deriv2 : public Base {
public:
virtual ~Deriv2(){}
};
void f(vector<Base *>& v){
v.push_back(new Deriv2); // oops, just pushed a Deriv2 into a vector of Deriv
}
如果您没有向向量添加元素,则只需传递一对输入迭代器即可。传递输出迭代器也不起作用。
template <typename InputIterator>
void f(InputIterator first, InputIterator last);
f(v.begin(), v.end());
答案 1 :(得分:3)
AFAIK不是您想要的方式(vector<Base*>
是与vector<Deriv*>
完全不同的类型。)
这是一种替代方法 - 这当然是一种通用算法
template <typename Iterator>
void f(Iterator begin, Iterator end)
{
// now do stuff...
}
致电
f(v.begin(), v.end());
答案 2 :(得分:1)
你应该在主
中写这个 Deriv *d = new Deriv;
vector<Base *> v; // Correction
v.push_back(d);
您仍然可以将Derived
个对象推入容器,f()
可以正常工作。
模板解决方案也很好:
template <typename T>
void f(std::vector<T>);
答案 3 :(得分:1)
Base
和Deriv
是协变类型,但std::vector<Base*>
和std::vector<Deriv*>
不是协变类型。
当X
是协变类型B
的对象时,您可以将D
派生的任何类型的对象B
分配给X
。这就是你的第一种情况。