doron
doron

Reputation: 28892

Copying from vector of derived class to vector of base class

I am looking for the simplest way to copy a vector of a derived class to a vector of a base class without doing it element by element. How can I fix the following to get this to work?

#include <vector>
#include <iostream>

struct A {
    A( int a) : a(a) {}
    int a;
};

struct B : public A {
    B (int a, int b) : A (a), b(b) {}
    int b;
};

int main() {
    std::vector<B> vb { B{1,2}, B{3,4}};
    std::vector<A> va = vb;
    for (const auto& item : va) {
        std::cout << item.a << " ";
    }
    std::cout << std::endl;
    return 0;
}

Right now I get the following error message from g++

error: conversion from ‘vector<B>’ to non-scalar type ‘vector<A>’ requested
   16 |     std::vector<A> va = vb;

Upvotes: 1

Views: 395

Answers (2)

doron
doron

Reputation: 28892

If you prefer composition over inheritance, you can use:

#include <vector>
#include <iostream>
#include <algorithm>

struct A {
    int a;
};

struct B {
    A a;
    int b;
};

int main() {
    std::vector<B> vb { {1 ,2},{3, 4} };
    std::vector<A> va;
    std::transform(vb.begin(), vb.end(), std::back_inserter(va), 
            [](const B& b) -> A { return b.a; } );
    for (const auto& item : va) {
        std::cout << item.a << " ";
    }
    std::cout << std::endl;
    return 0;
}

Upvotes: 0

songyuanyao
songyuanyao

Reputation: 172924

std::vector<A> can't be converted from std::vector<B> directly, they're two independent types substantially.

You can initialize va with the iterators of vb.

std::vector<A> va { vb.begin(), vb.end() };

Note that the elements of va would be slice-copied.

Upvotes: 1

Related Questions