4

假设我有一个基类和派生类,以及一个函数,它采用指向基类的指针的 stl 向量:

class A { public: int x; };

class B : public A { };

void foo(const vector<A*> &va) {
    for (vector<A*>::const_iterator it = va.begin(); it < va.end(); it++)
        cout << (*it)->x << endl;
}

有没有办法将指针列表传递给派生类?IE:

vector<B*> vb;
// ... add pointers to vb ...
foo(vb);

以上将导致以下编译器错误:

error: could not convert ‘vb’ from ‘std::vector<B*>’ to ‘std::vector<A*>’

即使 B* 可以转换为 A*。

最后,如果有纯指针的解决方案,它是否也适用于 boost 共享指针?

4

4 回答 4

5

std::vector<B*> and std::vector<A*>技术上不相关。C++ 不允许你想要的东西。

一种解决方法...为什么不使用std::vector<Base*>并插入Derived对象?这就是多态性、动态调度等的重点。

于 2012-10-12T23:20:47.703 回答
2

您可以从派生的基指针向量创建基指针的临时向量:

std::vector<B*> bv;
foo(std::vector<A*>(bv.begin(), bv.end())); 

但这要求 foo 接受 const 引用而不是像您的示例中那样引用,而且效率非常低,需要内存分配和复制,

其他首选解决方案是使您的 foo 成为功能模板:

template <class T>
void foo(std::vector<T*>& v);

为确保foo仅用于 A 派生,请使用 type_traits 和 SFINAE 技术,请注意您foo仅使用第一个参数调用,第二个仅用于消除非从 A 派生的类型的此函数模板(SFINAE):

#include <type_traits>

template <class T>
void foo(std::vector<T*>& av,
         // don't use this second param 
         typename std::enable_if<std::is_base_of<A,T>::value>::type* = 0)
于 2012-10-12T23:28:30.243 回答
2

正如@Science_Fiction 之前所说,拥有一个包含指向基本类型的指针并将指向基本类型和派生类型的指针插入其中的向量更有意义,但是如果您不控制这些数组的创建,则可以使用模板:

template <class T>
inline void foo(const vector<T*>& v)
{
    for (vector<T*>::const_iterator it = v.begin(); it < v.end(); ++it)
    {
        A* a = (A*) *it;
        cout << a->x << endl;
    }
}
于 2012-10-12T23:31:53.630 回答
1

您不能传递 a vector<B*>tofoo因为类型不兼容——B*隐式转换为A*.

您可以做的是创建一个vector正确类型的新的,例如:

vector<B*> vb;
// ... add pointers to vb ...

vector<A*> va(vb.size());
std::transform(vb.begin(), vb.end(), va.begin(),
               [] (B* p) { return static_cast<A*>(p); });
于 2012-10-12T23:21:02.057 回答