I have a snippet of code like this:
std::list<boost::shared_ptr<Point> > left, right;
// ... fill lists ...
// now, calculate the angle between (right[0], right[1]) and (right[0], left[0])
double alpha = angle(*(right.begin()->get()), *(((++right.begin()))->get()), *(left.begin()->get()) );
std::cout << alpha * 180 / M_PI << std::endl;
if(alpha < 0){
// do something with the lists, like reversing them. Especially the beginning and end of the lists may change in some way, but "left" and "right" are not reassigned.
}
// calculate the new alpha
alpha = angle(*(right.begin()->get()), *(((++right.begin()))->get()), *(left.begin()->get()) );
Apart from the iterator increment magic which may not be too obvoius here without the comments, I’d like to define a function double alpha() to reduce the duplication. But because the use of this function is very specific, I’d like to make it a local function. Ideally like that:
int a, b;
int sum(){ return a + b; }
a = 5; b = 6;
int s = sum(); // s = 11
a = 3;
s = sum(); // s = 9 now
In languages like Python this would be perfectly ok, but how to do this in C++?
EDIT:
This is what I ended up with, special thanks to @wilx and the -std=c++0x compiler flag:
auto alpha = [&right, &left]() {
// not 100% correct due to my usage of boost::shared_ptr, but to get the idea
Point r_first = *(right.begin());
Point l_first = *(left.begin());
Point r_second = *(++right.begin());
return angle(r_first, r_second, l_first);
};
if(alpha() < 0) // fix it
double new_alpha = alpha();
In this case I would suggest using an overload like
angle2(std::list<Point> const &, etc.). Two simple arguments is better than what you have now.With C++11 you could use lambdas that catch their arguments by reference.
If you cannot use C++11 and you do feel adventurous, try Boost.Phoenix (part of Boost.Spirit).