"Integration of the Standard Template Library and the Microsoft Foundation Class" - читать интересную книгу автора (Wolfgang Paul, Song Yang)

2.3.2 Drawing all strokes

In the original MFC implementation, the list of strokes was traversed and each stroke drawn by the following code:

POSITION pos = strokeList.front ();

while (pos!= NULL) {

 CStroke* pStroke = strokeList.GetNext(pos);

 pStroke-›DrawStroke(pDC);

}

We make two changes. The first obvious change is to replace the MFC list iteration with the corresponding STL iteration. The result is as follows:

for (std::list‹CStroke*›::iterator i = strokeList.begin(); i!= strokeList.end(); ++i)

 (*i)-›DrawStroke(pDC);

The second change is to apply the for_each algorithm. Unfortunately, the for_each algorithm takes as its third argument a function of one argument, that argument being the type obtained by de-referencing the iterator. Specifically, we must convert the expression:

(*i)-›DrawStroke(pDC);

into a call to a function of one argument, where that argument is the dereferenced iterator. Stroustrup[4] shows how to do this using the binders and adapters. The function mem_fun1 is a function of one parameter, the a pointer to member function that takes an arbitrary argument. The result of this function, is a function object that takes two arguments, the first of which is a pointer to a class, and the second is the same arbitrary second argument. Thus, the expression

(*i)-›DrawStroke(pDC);

may be replaced by

mem_fun1(amp;CStroke::DrawStroke)(*i, pDC);

We can now apply the bind2nd binder to convert this expression into a call to a function taking one argument:

bind2nd(mem_fun1(amp;CStroke::DrawStroke), pDC)(*i);

The loop can now be replaced by a call to the for_each algorithm:

for_each(strokeList.begin(), strokeList.end(), bind2nd(mem_fun1(amp;CStroke::DrawStroke), pDC));