You wouldn't use std::for_each
, but rather std::transform
(you're transforming a point into a single number.)
For example:
#include <algorithm> // transform resides here
#include <iostream>
#include <iterator>
#include <vector>
struct Point
{
int x;
int y;
Point(int x, int y) :
x(x),
y(y)
{
}
};
int point_to_int(const Point& p)
{
return p.x;
}
int main()
{
std::vector<Point> points;
points.push_back(Point(1, 2));
points.push_back(Point(4, 6));
std::vector<int> xs;
std::transform(points.begin(), points.end(),
std::back_inserter(xs), point_to_int);
std::copy(xs.begin(), xs.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
Because you know the size of the container you'll be transforming, you might get a slight performance improvement from the following. I also find it more readable:
std::vector<int> xs;
xs.reserve(points.size());
std::transform(points.begin(), points.end(),
std::back_inserter(xs), point_to_int);
And with boost::lambda
along with boost::bind
:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
struct Point
{
int x;
int y;
Point(int x, int y) :
x(x),
y(y)
{
}
};
int main()
{
using namespace boost;
std::vector<Point> points;
points.push_back(Point(1, 2));
points.push_back(Point(4, 6));
std::vector<int> xs;
xs.reserve(points.size());
std::transform(points.begin(), points.end(),
std::back_inserter(xs), bind(&Point::x, lambda::_1));
std::copy(xs.begin(), xs.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
Removes the need to specify a function elsewhere. This keeps the code close to the calling site, and generally improves readability.
In C++0x, it will simply be:
std::transform(points.begin(), points.end(),
std::back_inserter(xs), [](const Point& p){ return p.x; } );
(To the best of my knowledge, anyway)