std::vector 和多态性

发布于 2024-12-04 16:37:12 字数 684 浏览 0 评论 0原文

#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) 未找到。

我的问题:有没有办法让它工作:某种向量多态性?

#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;
}

The first f() works, but the second gives a compile time error:

f(vector<Deriv *>) not found.

My question: is there a way to make it work: some kind of polymorphism with vectors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假情假意假温柔 2024-12-11 16:37:12

您想要的属性称为协方差。答案是否定的,你不能这样做:向量不是协变的。

为什么不允许这样做的典型示例如下:

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());

The property you want is called covariance. And the answer is no, you cannot do this: vectors are not covariant.

The canonical example of why this is not allowed goes like this:

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
}

If you're not adding elements to the vector, you can just pass a pair of input iterators. Passing output iterators would not work either.

template <typename InputIterator>
void f(InputIterator first, InputIterator last);

f(v.begin(), v.end());
如梦 2024-12-11 16:37:12

AFAIK 不是您想要的方式(vectorvector 是根本不同的类型)。

这是一种替代方法 - 这当然是一种通用

template <typename Iterator>
void f(Iterator begin, Iterator end)
{
  // now do stuff...
}

算法

f(v.begin(), v.end());

AFAIK not the way you would like (vector<Base*> is a fundamentally different type to vector<Deriv*>).

Here's one alternative approach - this is of course a general algorithm

template <typename Iterator>
void f(Iterator begin, Iterator end)
{
  // now do stuff...
}

To call

f(v.begin(), v.end());
时间海 2024-12-11 16:37:12

您应该在 main 中编写此代码

  Deriv *d = new Deriv;
  vector<Base *> v;  // Correction
  v.push_back(d);

您仍然可以将 Derived 对象推送到容器中,并且 f() 工作正常。

模板解决方案也很好:

template <typename T>
void f(std::vector<T>);

You should write this in main

  Deriv *d = new Deriv;
  vector<Base *> v;  // Correction
  v.push_back(d);

You can still push the Derived objects into container and f() works fine.

Template solution is good as well:

template <typename T>
void f(std::vector<T>);
流绪微梦 2024-12-11 16:37:12

BaseDeriv 是协变类型,但 std::vectorstd::vector; 不是协变类型。

X 是协变类型 B 的对象时,您可以分配从 B 派生的任何类型 D 的对象,到X。这就是你的第一个案例中发生的情况。

Base and Deriv are covariant types, but std::vector<Base*> and std::vector<Deriv*> are not covariant types.

When X is an object of a covariant type B, you can assign object of any type D derive from B, to X. That is what happens in your first case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文