I have a C++
application with a struct
which looks like:
struct test_struc {
std::string name;
int x;
int y;
std::vector<int> data;
};
And I would like to transform two std::vector<test_struc>
using the lines according to their data
element in the structure. So far, I have the code:
std::vector<test_struc> first = <from somewhere else>;
std::vector<test_struc> second = <from somewhere else>;
std::vector<int> result;
std::transform (second.begin(), second.end(), first.begin(), result.begin(), op_xor);
where op_xor
is:
int op_xor (int &i,
int &j) {
return i^j;
}
This works well if first
and second
are vectors of int
, but since they are not, I don't know how to tell the code to use the data
element of test_struc
as arguments to std::transform
.
Am I barking up the wrong tree? Or is there a way to do this?
Note that at least with a modern compiler, you probably want to implement the operation as a lambda expression, so it would look something like:
std::transform(second.begin(), second.end(),
first.begin(),
std::back_inserter(result),
[](test_struct const &a, test_struct const &b) {
return a.y ^ b.y;
});
Minor aside: as it was, you had UB, trying to write through result.begin()
when the size of result
was 0. You could either use back_inserter
as above, or you could define result
initializing its size to second.size()
.
Your binary functor must take two test_struct
s:
int op_xor (const test_struct& i,
const test_struct& j)
{
return 42; // replace wit your desired logic.
}
It isn't clear what exactly you want the functor to do, but it should operate on the test_struct
s and return an int.
Or use lambdas. And remember size of other vectors must be the same or more than "second"
result.resize(second.size());
std::transform(second.begin(), second.end(), first.begin(), result.begin(),
[](test_struct & one, test_struct & two){ return one.x ^ two.x; });
But Jerry's example with back_inserter is better
Also you can do it using boost::transform and boost phoenix lambdas:
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
using boost::phoenix::arg_names::arg1;
using boost::phoenix::arg_names::arg2;
boost::transform(second, first, std::back_inserter(result), (&arg1)->*&test_struc::x ^ (&arg2)->*&test_struc::x);
First and second arguments of boost::transform
are ranges, so you do not have to write second.begin(), second.end(), first.begin()
here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.