Reputation: 28892
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
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
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