31. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Lambda Goodnesses : STL
(거의) 모든 STL 알고리즘은 lambda 함수를 지원합니다.
vector<int> v = ...;
for_each(v.begin(), v.end(), [](int x) { cout << x << ’ ’; });
// 특히 정렬에서 lambda 함수가 가장 유용하다.
// comparator를 번거롭게 만들거나, 먼 곳에 두지 않아도 됨!
sort(a.begin(), a.end(), [&](int x, int y) {
return priority[x] > priority[y];
});
auto by_abs = [](int x, int y) { return abs(x) < abs(y); });
sort(a.begin(), a.end(), by_abs);
32. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Lambda Goodnesses : Local functions
C++03 에서는, local type 선언은 가능하지만 template argument
로 사용이 불가능하다. 따라서 sort의 comparator 로 사용할 수 없어
함수 바깥으로 빼야하는 불편함이 있었다.
void localFunction( vector<int> &data ) {
struct AbsComparator {
bool operator() (const int a, const int b) {
return abs(a) < abs(b);
};
};
sort(data.begin(), data.end(), AbsComparator()); // ERROR in C++03, O in C++11
}
33. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Lambda Goodnesses : Local functions
마찬가지로 lambda를 사용하면, 해당 함수가 사용되는 곳에서 코드를
작성할 수 있으므로 전역 변수의 사용을 피하고 code의 locality를 키울
수 있으므로 좋다.
// Using Lambda : ind of local functions (even can capture local variables)
void localFunction( const vector<point> &P ) {
const point O = P[0]; // reference 사용하지 않도록 주의 (why?)
auto by_distance = [&](const point &A, const point &B) {
double OA = (A - base).norm();
double OB = (B - base).norm();
return OA < OB;
};
sort(P.begin(), P.end(), by_distance); // O
}
Closure 덕택에 contextual variable 를 사용할 수 있다.
34. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Lambda Goodnesses : 예제 (1)
int solve(vector<int> &a, vector<int> &b) {
int n = (int) a.size();
int S = 0, T = V - 1;
int V = 2 * n + 2;
auto L = [&](int x) { return x + 1; };
auto R = [&](int x) { return x + 1 + n; };
NetworkFlow f(V);
for(int i=0; i<n; ++i) {
f.addEdge(S, L(i), a[i]);
f.addEdge(L(i), R(i), a[i]);
f.addEdge(R(i), T, b[i]);
}
/* ... */
}