如何将子类的向量传递给需要基类向量的函数

时间:2018-03-02 21:52:55

标签: c++ stdvector

我有一个 Base 类和一个 Sub 类:

class Base{
  public:
    Base(){}
    // ...
};

class Sub: public Base{
    int param;
  public:
    Sub(){}
    // ...
};

我还有一个需要 Base vector 的函数,如下所示:

void doSomeThing(vector<Base> vectorOfBases){
    // ...
}

我需要调用这样的函数:

vector<Sub> myVectorOfSubs;
doSomeThing(myVectorOfSubs);

编译器告诉我:

  

没有来自vector&lt;的适当转换。 Sub>矢量&lt;基地&gt;

那么如何将Sub类的向量传递给需要Base类向量的函数?

2 个答案:

答案 0 :(得分:3)

vector<Base>vector<Sub>分别拥有实际的BaseSub个对象。它们是不同的矢量类型,它们的数据数组不同,因此您无法通过vector<Sub>预期vector<Base>。如果尝试使用vector<Base>对象构建Subslicing will occur

要使代码有效,您可以:

  • 更改函数以取代vector<Base*>,然后您可以构建一个vector<Base*>,其元素指向您的vector<Sub>元素,例如:

    void doSomeThing(std::vector<Base*> &vectorOfBasePtrs) {
        for (Base *b : vectorOfBasePtrs) {
            // ...
        }
    }
    

    std::vector<Sub> myVectorOfSubs;
    ...
    
    std::vector<Base*> myVectorOfBasePtrs;
    
    myVectorOfBasePtrs.resize(myVectorOfSubs.size());
    std::transform(myVectorOfSubs.begin(), myVectorOfSubs.end(), myVectorOfBasePtrs.begin(),
        [](Sub &s){ return static_cast<Base*>(&s); }
    );
    
    /* or:
    myVectorOfBasePtrs.reserve(myVectorOfSubs.size());
    for (Sub &s : myVectorOfSubs) {
        myVectorOfBasePtrs.push_back(&s);
    }
    */
    
    doSomeThing(myVectorOfBasePtrs);
    
  • 更改功能以vector<T> T,其中T是模板参数(最好通过std::enable_ifstd::is_base_of使用SFINAE以确保Base 1}}实际上是Base或从template<typename T> void doSomeThing(std::vector<T> &vectorOfObjs) { for (Base &b : vectorOfObjs) { // ... } } 派生的类型:

    std::vector<Sub> myVectorOfSubs;
    ...
    
    doSomeThing(myVectorOfSubs);
    

    T
  • 更改函数以对实际容器采用模板template<typename Container> void doSomeThing(Container &containerOfObjs) { for (Base &b : containerOfObjs) { // ... } } 而不是容器元素类型:

    vector<Sub>
  • 更改函数以获取一对迭代器而不是容器本身,然后您可以从template <typename Iterator> void doSomeThing(Iterator begin, Iterator end) { while (begin != end) { Base &b = *begin; // ... ++begin; } } 传递迭代器:

    std::vector<Sub> myVectorOfSubs;
    ...
    
    doSomeThing(myVectorOfSubs.begin(), myVectorOfSubs.end());
    

    {"ts":"2018-01-04T02:19:05.144-06:00","ct":"{\"Antenna\":3,\"OlioId\":1,\"TagId\":\"30742C40A426936D4B681B3E\",\"TimeStamp\":\"2018-01-04T02:19:05.144-06:00\"}"}
    {"ts":"2018-01-04T02:19:05.167-06:00","ct":"{\"Antenna\":3,\"OlioId\":1,\"TagId\":\"307405B6E8538FED4B68F19F\",\"TimeStamp\":\"2018-01-04T02:19:05.167-06:00\"}"}
    {"ts":"2018-01-04T02:19:05.214-06:00","ct":"{\"Antenna\":4,\"OlioId\":1,\"TagId\":\"30742C40A426936D4B691D5D\",\"TimeStamp\":\"2018-01-04T02:19:05.214-06:00\"}"}
    {"ts":"2018-01-04T02:19:05.448-06:00","ct":"{\"Antenna\":6,\"OlioId\":1,\"TagId\":\"30742C40A42692ED4B67CD2E\",\"TimeStamp\":\"2018-01-04T02:19:05.448-06:00\"}"}
    

答案 1 :(得分:0)

  

那么如何将Sub类的向量传递给需要Base类向量的函数?

你不能。

std::vector<Base>std::vector<Sub>之间没有超类 - 次级联系。

这是克服这种限制的一种方法。更改函数以使用可以与包含BaseSub个对象的任何容器一起使用的函数模板。

template <typename Container>
void doSomeThing(Container& container)
{
   // Do something for each item of the container assuming that
   // the container contains objects of type Base or any of its derived classes.
   for ( Base& baseRef : container )
   {
     // Use baseRef
   }
}