std::for_each
오버 for
루프의 장점이 있습니까? 나에게 std::for_each
코드의 가독성을 방해하는 것 같습니다. 그렇다면 일부 코딩 표준에서 사용을 권장하는 이유는 무엇입니까?
std::for_each
오버 for
루프의 장점이 있습니까? 나에게 std::for_each
코드의 가독성을 방해하는 것 같습니다. 그렇다면 일부 코딩 표준에서 사용을 권장하는 이유는 무엇입니까?
답변:
C ++ 11 (이전의 C ++ 0x) 의 좋은 점 은이 지루한 논쟁이 해결 될 것입니다.
전체 컬렉션을 반복하고 싶어하는 올바른 마음을 가진 사람은 여전히 이것을 사용하지 않습니다.
for(auto it = collection.begin(); it != collection.end() ; ++it)
{
foo(*it);
}
아니면 이거
for_each(collection.begin(), collection.end(), [](Element& e)
{
foo(e);
});
시 영역 기반 for
루프 구문을 사용할 수있다 :
for(Element& e : collection)
{
foo(e);
}
이러한 종류의 구문은 Java 및 C #에서 한동안 사용 가능했으며 실제로는 최근에 본 모든 Java 또는 C # 코드에서 foreach
기존 for
루프 보다 더 많은 루프 가 있습니다.
Element & e
대로 auto & e
(또는 auto const &e
) 더 나은 보인다. 내가 사용하는 거라고 Element const e
내가 암시 적 변환을 할 때, 소스가 다른 종류의 모음입니다 말할 때, 나는 그들로 변환 할 (관계없이) Element
.
몇 가지 이유는 다음과 같습니다.
익숙하지 않거나 읽기 쉬운 도구를 사용하지 않아서 가독성을 방해하는 것 같습니다. (헬퍼의 경우 boost :: range 및 boost :: bind / boost :: lambda를 참조하십시오. 이들 중 다수는 C ++ 0x로 이동하여 for_each 및 관련 함수를보다 유용하게 만듭니다.)
모든 반복자와 작동하는 for_each 위에 알고리즘을 작성할 수 있습니다.
어리석은 타이핑 버그의 가능성을 줄입니다.
또한, 같은 STL-알고리즘의 나머지에 당신의 마음을 열고 find_if
, sort
, replace
, 등 이들은 더 이상 이상한 보이지 않는 것입니다. 이것은 큰 승리가 될 수 있습니다.
업데이트 1 :
가장 중요한 것은, 그것이 for_each
존재하는 모든 것과 같은 for-loops를 넘어서서 find / sort / partition / copy_replace_if, parallel execution .. 또는 무엇이든과 같은 다른 STL- 알고리즘을 살펴 보는 것입니다.
for_each의 형제의 "나머지"를 사용하여 많은 처리를 매우 간결하게 작성할 수 있지만 다양한 내부 논리를 사용하여 for-loop를 작성하는 것만으로도 그 사용법을 배우지 못할 것입니다. 바퀴를 반복해서 발명하게됩니다.
(곧 사용 가능한 범위 스타일 for_each) :
for_each(monsters, boost::mem_fn(&Monster::think));
또는 C ++ x11 람다 :
for_each(monsters, [](Monster& m) { m.think(); });
IMO가 다음보다 더 읽기 쉽습니다.
for(Monsters::iterator i = monsters.begin(); i != monsters.end(); ++i) {
i->think();
}
또한 이것 (또는 람다와 함께, 다른 사람들을보십시오) :
for_each(bananas, boost::bind(&Monkey::eat, my_monkey, _1));
다음보다 더 간결합니다.
for(Bananas::iterator i = bananas.begin(); i != bananas.end(); ++i) {
my_monkey->eat(*i);
}
특히 여러 함수를 순서대로 호출하는 경우 ...하지만 아마도 나뿐입니다. ;)
업데이트 2 : 반복자 쌍 대신 범위와 함께 작동하는 자체 stl-algos 래퍼를 작성했습니다. boost :: range_ex가 출시되면 C ++ 0x에도 포함됩니까?
outer_class::inner_class::iterator
또는 템플릿 인수 : typename std::vector<T>::iterator
... for 구문 자체가 자체적으로 많은 행 구문으로 실행될 수 있습니다.
for_each
두 번째 예에서 잘못된 것임for_each( bananas.begin(), bananas.end(),...
for_each
더 일반적입니다. 시작 / 종료 반복자를 전달하여 모든 유형의 컨테이너를 반복하는 데 사용할 수 있습니다. for_each
반복 코드를 업데이트하지 않고도 사용하는 함수 아래에서 컨테이너를 교체 할 수 있습니다 . 세상에는 다른 std::vector
오래된 컨테이너 와 일반 C 어레이의 이점을 보려면 다른 컨테이너가 있다는 것을 고려해야합니다 for_each
.
가장 큰 단점은 for_each
functor가 필요하기 때문에 구문이 복잡하다는 것입니다. 이것은 람다를 도입하여 C ++ 11 (이전 C ++ 0x)에서 수정되었습니다.
std::vector<int> container;
...
std::for_each(container.begin(), container.end(), [](int& i){
i+= 10;
});
3 년 후에는 이상하게 보이지 않을 것입니다.
for ( int v : int_vector ) {
(이 BOOST_FOREACH 오늘 시뮬레이션 할 수 있습니다 경우에도)
std::for_each(container, [](int& i){ ... });
. 왜 컨테이너를 두 번 쓰도록 강요합니까?
container.each { ... }
시작 및 끝 반복자를 언급하지 않고 같은 것을 작성 합니다. 끝 반복기를 항상 지정 해야하는 것이 조금 중복됩니다.
개인적으로, 사용 방법을 std::for_each
벗어나야 할 때마다 (특수 기능 펑터 작성 / 복잡한 작성 boost::lambda
) BOOST_FOREACH
C ++ 0x의 범위 기반을 사용하여 더 명확하게 알 수 있습니다.
BOOST_FOREACH(Monster* m, monsters) {
if (m->has_plan())
m->act();
}
vs
std::for_each(monsters.begin(), monsters.end(),
if_then(bind(&Monster::has_plan, _1),
bind(&Monster::act, _1)));
매우 주관적이며 일부는 동일한 규칙으로 다른 컬렉션을 처리 할 수 있기 때문에 for_each
코드를 더 읽기 쉽게 만들 것이라고 말합니다 .
for_each
itslef는 루프로 구현됩니다
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
그래서 당신에게 맞는 것을 선택하는 것은 당신에게 달려 있습니다.
많은 알고리즘 함수와 마찬가지로 초기 반응은 루프보다 foreach를 사용하는 것이 더 읽기 어렵다고 생각하는 것입니다. 많은 화염 전쟁의 주제였습니다.
관용구에 익숙해지면 유용 할 수 있습니다. 명백한 이점 중 하나는 코더가 루프의 내부 내용을 실제 반복 기능과 분리하도록 강제한다는 것입니다. (OK, 그것이 이점이라고 생각합니다. 다른 사람들은 당신이 실제로 이익을 얻지 않고 코드를 자르고 있다고 말합니다).
다른 장점은 foreach를 볼 때 모든 항목이 처리되거나 예외가 발생한다는 것을 알고 있습니다.
에 대한 루프는 루프를 종료하는 몇 가지 옵션이 있습니다. 루프가 전체 과정을 실행하도록하거나 break 키워드를 사용하여 루프에서 명시 적으로 점프하거나 return 키워드를 사용 하여 전체 함수 중간 루프를 종료 할 수 있습니다. 반대로, foreach 는 이러한 옵션을 허용하지 않으므로 더 읽기 쉽습니다. 함수 이름을 한 눈에 볼 수 있으며 반복의 전체 특성을 알 수 있습니다.
혼란스러운 for 루프 의 예는 다음과 같습니다 .
for(std::vector<widget>::iterator i = v.begin(); i != v.end(); ++i)
{
/////////////////////////////////////////////////////////////////////
// Imagine a page of code here by programmers who don't refactor
///////////////////////////////////////////////////////////////////////
if(widget->Cost < calculatedAmountSofar)
{
break;
}
////////////////////////////////////////////////////////////////////////
// And then some more code added by a stressed out juniour developer
// *#&$*)#$&#(#)$#(*$&#(&*^$#(*$#)($*#(&$^#($*&#)$(#&*$&#*$#*)$(#*
/////////////////////////////////////////////////////////////////////////
for(std::vector<widgetPart>::iterator ip = widget.GetParts().begin(); ip != widget.GetParts().end(); ++ip)
{
if(ip->IsBroken())
{
return false;
}
}
}
std::for_each()
(즉,이 게시물의 시간) 기존의 표준에 당신은 당신이 말한대로 가독성을 장려하고 조기에 루프의 돌발 금지 명명 된 펑터를 사용해야합니다. 그러나 등가 for
루프에는 함수 호출 만이 없으며 너무 빠르지 않습니다. 하지만 당신이 그 말에 훌륭한 포인트를 만든 생각 이외 std::for_each()
시행한다 전체 범위를 겪고 있습니다.
대부분 정확합니다. 대부분의 경우 std::for_each
순 손실입니다. 나는 비교 for_each
하기 위해 갈 것입니다 goto
. goto
가능한 가장 다양한 흐름 제어 기능을 제공합니다. 상상할 수있는 거의 모든 다른 제어 구조를 구현하는 데 사용할 수 있습니다. 그러나 그 다재다능 함 goto
은 고립 된 상태 를 보는 것이이 상황에서 의도 한 바에 대해 거의 아무 것도 알려주지 않음을 의미합니다 . 결과적 goto
으로, 최후의 수단을 제외하고 는 올바른 마음을 가진 사람은 거의 없습니다 .
표준 알고리즘 중에서도 for_each
거의 동일한 방식입니다. 사실상 모든 것을 구현하는 데 사용할 수 있습니다. 즉, for_each
이 상황에서 어떤 것이 사용되고 있는지에 대해 전혀 알 수 없습니다. 불행하게도, 사람들의 태도 for_each
는 goto
1970 년 정도 의 태도 에 관한 것입니다. 소수의 사람들은 최후의 수단으로 만 사용해야한다는 사실에 사로 잡혀 있었지만, 여전히 많은 사람들이 그것을 기본 알고리즘으로 생각합니다. 다른 것을 사용하는 경우는 거의 없습니다. 대부분의 시간, 심지어 한 눈에 볼 때 대안 중 하나가 크게 우수했음을 알 수 있습니다.
예를 들어, 사람들이을 사용하여 컬렉션의 내용을 인쇄하기 위해 코드를 작성하는 것을 본 횟수를 잊어 버렸습니다 for_each
. 내가 본 게시물을 기반으로하여 가장 일반적인 단일 사용 일 수 있습니다 for_each
. 그들은 다음과 같이 끝납니다 :
class XXX {
// ...
public:
std::ostream &print(std::ostream &os) { return os << "my data\n"; }
};
그리고 그 이후는 어떤 조합에 대해 요구하고있다 bind1st
, mem_fun
등 그들이 같은 것을 할 필요가 :
std::vector<XXX> coll;
std::for_each(coll.begin(), coll.end(), XXX::print);
작업하고의 요소를 인쇄하십시오 coll
. 실제로 내가 작성한 그대로 정확하게 작동한다면 평범하지는 않지만 작동하지 않을 때 코드와 관련된 몇 가지 코드를 찾기가 어렵습니다. 그것을 붙들고있는 조각들 사이에서 진행됩니다.
다행히도 더 좋은 방법이 있습니다. XXX에 일반 스트림 삽입 기 과부하를 추가합니다.
std::ostream &operator<<(std::ostream *os, XXX const &x) {
return x.print(os);
}
그리고 사용 std::copy
:
std::copy(coll.begin(), coll.end(), std::ostream_iterator<XXX>(std::cout, "\n"));
그 작업을 수행 -하고의 내용을 인쇄하는 것을 알아 내기 위해 모두에서 실질적으로 일을지지 않습니다 coll
에를 std::cout
.
boost::mem_fn(&XXX::print)
XXX::print
std::cout
.
가독성을 높이기위한 기능 작성의 이점은 언제 for(...)
및 for_each(...
)에 나타나지 않을 수 있습니다 .
for-loops를 사용하는 대신 functional.h의 모든 알고리즘을 사용하면 코드를 훨씬 더 읽기 쉽게 할 수 있습니다.
iterator longest_tree = std::max_element(forest.begin(), forest.end(), ...);
iterator first_leaf_tree = std::find_if(forest.begin(), forest.end(), ...);
std::transform(forest.begin(), forest.end(), firewood.begin(), ...);
std::for_each(forest.begin(), forest.end(), make_plywood);
이다 훨씬 더 읽기보다는;
Forest::iterator longest_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (*it > *longest_tree) {
longest_tree = it;
}
}
Forest::iterator leaf_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (it->type() == LEAF_TREE) {
leaf_tree = it;
break;
}
}
for (Forest::const_iterator it = forest.begin(), jt = firewood.begin();
it != forest.end();
it++, jt++) {
*jt = boost::transformtowood(*it);
}
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
std::makeplywood(*it);
}
그리고 그것이 내가 생각하는 것입니다 .for 루프를 한 줄 함수로 일반화하십시오 =)
쉬움 : for_each
모든 배열 항목을 처리하는 함수가 이미있을 때 유용하므로 람다를 작성할 필요가 없습니다. 확실히, 이것은
for_each(a.begin(), a.end(), a_item_handler);
~보다 낫다
for(auto& item: a) {
a_item_handler(a);
}
또한, 원거리 for
루프는 전체 컨테이너를 처음부터 끝까지 반복하는 반면, for_each
더 유연합니다.
for_each
루프 작동에 대한 명확한 의미를 사용자 코드에서 반복자 (루프 구현 방법의 세부 사항) 숨기고 정의하기위한 것입니다 : 각 요소는 정확히 한 번만 반복됩니다.
현재 표준에서 가독성 문제는 코드 블록 대신 마지막 인수로 functor가 필요하므로 많은 경우 특정 functor 유형을 작성해야한다는 것입니다. functor 객체를 제자리에서 정의 할 수없고 (함수 내에 정의 된 로컬 클래스를 템플릿 인수로 사용할 수 없음) 루프 구현을 실제 루프에서 멀리 옮겨야하므로 읽기 어려운 코드로 바뀝니다.
struct myfunctor {
void operator()( int arg1 ) { code }
};
void apply( std::vector<int> const & v ) {
// code
std::for_each( v.begin(), v.end(), myfunctor() );
// more code
}
각 객체에 대해 특정 작업을 수행하려는 경우 std::mem_fn
, 또는 boost::bind
( std::bind
다음 표준에서) 또는 boost::lambda
(다음 표준에서 람다)를 사용하여 간단하게 만들 수 있습니다.
void function( int value );
void apply( std::vector<X> const & v ) {
// code
std::for_each( v.begin(), v.end(), boost::bind( function, _1 ) );
// code
}
호출 할 함수 / 메소드가있는 경우 핸드 롤 버전보다 덜 읽기 쉽고 컴팩트하지 않습니다. 구현시 for_each
루프 의 다른 구현을 제공 할 수 있습니다 (병렬 처리 생각).
다가오는 표준은 몇 가지 단점을 다른 방식으로 처리하며 템플릿에 대한 인수로 로컬로 정의 된 클래스를 허용합니다.
void apply( std::vector<int> const & v ) {
// code
struct myfunctor {
void operator()( int ) { code }
};
std::for_each( v.begin(), v.end(), myfunctor() );
// code
}
코드의 지역성 향상 : 탐색 할 때 코드의 기능을 확인할 수 있습니다. 사실, functor를 정의하기 위해 클래스 구문을 사용할 필요는 없지만 람다를 사용하십시오.
void apply( std::vector<int> const & v ) {
// code
std::for_each( v.begin(), v.end(),
[]( int ) { // code } );
// code
}
경우에 따라 for_each
더 자연스럽게 만드는 구체적인 구성이있을 것입니다.
void apply( std::vector<int> const & v ) {
// code
for ( int i : v ) {
// code
}
// code
}
나는 for_each
구조를 수동 롤 루프와 혼합하는 경향이 있습니다. 기존 함수 또는 메소드에 대한 호출 만 필요한 경우 ( for_each( v.begin(), v.end(), boost::bind( &Type::update, _1 ) )
) for_each
코드에서 많은 보일러 플레이트 반복기 항목을 제거 하는 구문을 사용합니다. 더 복잡한 것이 필요하고 실제 사용보다 몇 줄만 functor를 구현할 수없는 경우 내 루프를 롤링합니다 (작업을 유지합니다). 중요하지 않은 코드 섹션에서 BOOST_FOREACH와 함께 갈 수 있습니다 (동료가 나를 데려갔습니다)
가독성과 성능 외에도 일반적으로 간과되는 한 가지 측면은 일관성입니다. for (또는 while) 루프 오버 반복자를 구현하는 방법에는 여러 가지가 있습니다.
for (C::iterator iter = c.begin(); iter != c.end(); iter++) {
do_something(*iter);
}
에:
C::iterator iter = c.begin();
C::iterator end = c.end();
while (iter != end) {
do_something(*iter);
++iter;
}
다양한 수준의 효율성과 버그 가능성 사이에 많은 예가 있습니다.
그러나 for_each를 사용하면 루프를 추상화하여 일관성을 유지합니다.
for_each(c.begin(), c.end(), do_something);
현재 걱정해야 할 것은 Boost 또는 C ++ 0x 기능을 사용하여 루프 바디를 함수, 펑터 또는 람다로 구현합니까? 개인적으로, 무작위 for / while 루프를 구현하거나 읽는 방법보다 걱정이됩니다.
나는 std::for_each
람다가 없으면 완전히 잘못되었다고 싫어 하고 생각했습니다. 그러나 나는 얼마 전에 내 마음을 바꾸었고, 지금은 실제로 그것을 좋아합니다. 또한 가독성을 향상시키고 TDD 방식으로 코드를 쉽게 테스트 할 수 있다고 생각합니다.
std::for_each
알고리즘은 다음과 같이 읽을 수있는 범위에있는 모든 요소와 함께 할 일 , 할 수 가독성을 향상시킬 수 있습니다. 수행하려는 조치의 길이가 20 줄이고 조치가 수행되는 기능의 길이도 약 20 줄이라고 가정하십시오. 그것은 전통적인 for 루프로 40 줄 길이의 함수를 만들고, 약 20으로 만 함수 std::for_each
를 이해하기 쉬울 것입니다.
펑 터는 다음 std::for_each
과 같이보다 일반적이고 재사용이 가능합니다.
struct DeleteElement
{
template <typename T>
void operator()(const T *ptr)
{
delete ptr;
}
};
그리고 코드 std::for_each(v.begin(), v.end(), DeleteElement())
에는 명시 적 루프보다 약간 더 나은 IMO 와 같은 하나의 라이너 만 있습니다 .
이러한 함수는 일반적으로 긴 함수 중간에 명시 적 for 루프보다 단위 테스트를 받기가 더 쉽고 그 자체만으로도 이미 큰 승리입니다.
std::for_each
범위에 실수를 할 가능성이 적으므로 일반적으로 더 안정적입니다.
마지막으로 컴파일러는 std::for_each
특정 유형의 수작업 for 루프보다 약간 더 나은 코드를 생성 할 수 있습니다. for (each) 는 컴파일러에 대해 항상 동일하게 보이고 컴파일러 작성자는 자신의 지식을 최대한 활용할 수 있도록 모든 지식을 넣을 수 있습니다. 할 수있다.
같은 같은 다른 표준 알고리즘을 적용 find_if
, transform
등
for
각 요소를 반복 할 수있는 for 루프입니다 .3 분의 1 등 for_each
은 각 요소를 반복하기위한 것입니다. 그것의 이름에서 분명하다. 따라서 코드에서 수행하려는 작업이 더 명확합니다.
++
. 특이 할 수도 있지만 for-loop도 마찬가지입니다.
transform
누군가를 혼동하지 않기 위해 사용 하는 것이 좋습니다 .
STL에서 다른 알고리즘을 자주 사용하는 경우 다음과 같은 장점이 있습니다 for_each
.
기존의 for 루프와 달리 for_each
입력 반복기에 사용할 수있는 코드를 작성해야합니다. 이런 식으로 제한되는 것은 실제로 다음과 같은 이유로 좋은 것일 수 있습니다.
for_each
.사용 for_each
때때로하면 같은 일을 할 수있는보다 구체적인 STL 기능을 사용할 수있는 더 분명합니다. (Jerry Coffin의 예에서와 같이; 반드시 for_each
최선의 선택 인 경우 는 아니지만 for 루프가 유일한 대안은 아닙니다.)
C ++ 11과 두 개의 간단한 템플릿을 사용하면
for ( auto x: range(v1+4,v1+6) ) {
x*=2;
cout<< x <<' ';
}
대체 for_each
또는 루프로. 왜 그것을 선택하면 간결성과 안전으로 귀결되며, 표현에 오류가 없을 가능성이 없습니다.
나를 위해, for_each
루프 바디가 이미 펑 터일 때 항상 동일한 근거에서 나아졌으며, 내가 얻을 수있는 모든 이점을 활용할 것입니다.
여전히 three-expression for
을 사용하지만 이제 이해해야 할 것이 있다는 것을 알면 보일러 플레이트가 아닙니다. 나는 상용구가 싫어 . 나는 그 존재를 원망했다. 그것은 실제 코드가 아니며, 그것을 읽음으로써 배울 것이 없으며, 점검해야 할 또 하나의 것입니다. 정신적 노력은 점검하는 것이 얼마나 녹슬 었는지 쉽게 측정 할 수 있습니다.
템플릿은
template<typename iter>
struct range_ {
iter begin() {return __beg;} iter end(){return __end;}
range_(iter const&beg,iter const&end) : __beg(beg),__end(end) {}
iter __beg, __end;
};
template<typename iter>
range_<iter> range(iter const &begin, iter const &end)
{ return range_<iter>(begin,end); }
대부분 전체 컬렉션 을 반복 해야합니다 . 따라서 두 개의 매개 변수 만 사용하여 고유 한 for_each () 변형을 작성하는 것이 좋습니다. 이를 통해 Terry Mahaffey의 예 를 다음과 같이 다시 작성할 수 있습니다 .
for_each(container, [](int& i) {
i += 10;
});
나는 이것이 실제로 for 루프보다 더 읽기 쉽다고 생각합니다. 그러나 여기에는 C ++ 0x 컴파일러 확장이 필요합니다.
for_each가 가독성에 좋지 않다는 것을 알았습니다. 개념은 좋은 것이지만 c ++은 적어도 나에게 읽기가 매우 어렵습니다. c ++ 0x lamda 표현식이 도움이 될 것입니다. 나는 람다의 아이디어를 정말로 좋아한다. 그러나 언뜻보기에 나는 구문이 매우 추악하다고 생각하고 그것에 익숙해 질 것이라고 100 % 확신하지 못합니다. 어쩌면 5 년 후에는 익숙해 져서 다시 생각하지 않을 것입니다. 시간이 말해 줄거야 :)
나는 사용하는 것을 선호합니다
vector<thing>::iterator istart = container.begin();
vector<thing>::iterator iend = container.end();
for(vector<thing>::iterator i = istart; i != iend; ++i) {
// Do stuff
}
시작 및 종료 반복자에 대해 명명 된 변수를 사용하여 명시 적 for 루프가 더 명확하게 읽고 명시 적으로 발견하여 for 루프의 혼란을 줄입니다.
물론 경우에 따라 다를 수 있습니다. 이것이 제가 가장 일반적으로 찾는 것입니다.
반복자를 루프를 통해 각 반복에서 수행되는 함수에 대한 호출로 만들 수 있습니다.
여기를 참조하십시오 : http://www.cplusplus.com/reference/algorithm/for_each/
for_each
입니다.이 경우 이점에 대한 질문에 대답하지 않습니다.
For 루프가 깨질 수 있습니다. 나는 Herb Sutter의 앵무새가되고 싶지 않으므로 여기에 그의 프리젠 테이션에 대한 링크가 있습니다 : http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T 또한 의견을 읽으십시오 :)
for_each
포크 조인 패턴 을 구현할 수 있습니다. 그 외에는 유창한 인터페이스를 지원 합니다 .
gpu::for_each
여러 작업자에서 람다 작업을 호출하여 이기종 병렬 컴퓨팅에 cuda / gpu를 사용하도록 구현 을 추가 할 수 있습니다 .
gpu::for_each(users.begin(),users.end(),update_summary);
// all summary is complete now
// go access the user-summary here.
그리고 gpu::for_each
다음 명령문을 실행하기 전에 작업자가 모든 람다 작업이 완료 될 때까지 기다릴 수 있습니다.
이를 통해 사람이 읽을 수있는 코드를 간결하게 작성할 수 있습니다.
accounts::erase(std::remove_if(accounts.begin(),accounts.end(),used_this_year));
std::for_each(accounts.begin(),accounts.end(),mark_dormant);
std::for_each
가독성 과 함께 사용boost.lambda
하거나boost.bind
가독성을 향상시킬 수있는 경우