Given a std::vector
which holds objects of MyClass. How can I create another vector which holds just data of one member of MyClass using std::copy
? I guess I would have to implement a custom back_inserter
but I could not figure out how to do this so far.
struct MyClass {
int a;
}
std::vector<MyClass> vec1;
// I could copy that to another vector of type MyClass using std::copy.
std::copy(vec1.begin(), vec1.end(); std::back_inserter(someOtherVec)
// However I want just the data of the member a, how can I do that using std::copy?
std::vector<int> vec2;
Use std::transform
for that.
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2),
[](const MyClass& cls) { return cls.a; });
(If you can't use C++11, you could make a function object yourself:
struct AGetter { int operator()(const MyClass& cls) const { return cls.a; } };
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), AGetter());
or use std::tr1::bind
if you can use TR1:
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2),
std::tr1::bind(&MyClass::a, std::tr1::placeholders::_1));
BTW, as @Nawaz commented below, do a .reserve()
to prevent unnecessary reallocation during the copy.
vec2.reserve(vec1.size());
std::transform(...);
You want to use std::transform
not std::copy
and std::bind
to bind to a pointer to a member variable:
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <functional>
struct foo {
int a;
};
int main() {
const std::vector<foo> f = {{0},{1},{2}};
std::vector<int> out;
out.reserve(f.size());
std::transform(f.begin(), f.end(), std::back_inserter(out),
std::bind(&foo::a, std::placeholders::_1));
// Print to prove it worked:
std::copy(out.begin(), out.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
My example is C++11, but if you skip the handy vector initalization and use boost::bind
instead this works just as well without C++11.