# Effective STL Item 43：优先使用STL泛型算法以取代手写循环 (转)

Effective STL Item 43：优先使用STL泛型算法以取代手写循环 (转)[@more@]

STL泛型算法vs.手写的循环XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

SCOtt Meyers

-------------------------------------------------------------------------------

[这篇文章源自一本即将出版的书。S. Meyers，Effective STL:50 Specific Ways to Improve Your Use of the Standard Template Library，改自Item 26-28（WQ注，CUJ上原文如此，应为Item 43）。 2001 Addison-Wesley。 发行：peRmission of Pearson Education, Inc]

class Widget {

public:

...

void redraw() const;

...

};

list lw;

...

for (list::iterator i =

lw.begin();

i != lw.end(); ++i) {

i->redraw();

}

for_each(lw.begin(), lw.end(),

mem_fun_ref(&Widget::redraw));

for (list::iterator i =

lw.begin();

i != lw.end();

++i) {

i->redraw();

}

// this call evaluates lw.end() exactly

// once

for_each(lw.begin(), lw.end(),

mem_fun_ref(&Widget::redraw));

// C api: this function takes a pointer

// to an array of at most arraySize

// doubles and writes data to it. It

// returns the number of doubles written.

size_t fillArray(double *pArray, size_t arraySize);

// create local array of max possible size

double data[maxNumDoubles];

// create deque, put data into it

deque d;

...

// get array data from API

size_t numDoubles =

fillArray(data, maxNumDoubles);

// for each i in data, insert data[i]+41

// at the front of d; this code has a bug!

for (size_t i = 0; i < numDoubles; ++i) {

d.insert(d.begin(), data[i] + 41);

}

// remember d’s begin iterator

deque::iterator insertLocation = d.begin();

// insert data[i]+41 at insertLocation, then

// increment insertLocation; this code is also buggy!

for (size_t i = 0; i < numDoubles; ++i) {

d.insert(insertLocation++, data[i] + 41);

}

deque::iterator insertLocation =

d.begin();

// update insertLocation each time

// insert is called to keep the iterator valid,

// then increment it

for (size_t i = 0; i < numDoubles; ++i) {

insertLocation =

d.insert(insertLocation, data[i] + 41);

++insertLocation;

}

// copy all elements from data to the

// front of d, adding 41 to each

transform(data, data + numDoubles,

inserter(d, d.begin()),

bind2nd(plus(), 41));

vector v;

int x, y;

...

// iterate from v.begin() until an

// appropriate value is found or

// v.end() is reached

vector::iterator i = v.begin();

for( ; i != v.end(); ++i) {

if (*i > x && *i < y) break;

}

// i now points to the value

// or is the same as v.end()

// find the first value val where the

// "and" of val > x and val < y is true

vector iterator i =

find_if(v.begin(), v.end(),

compose2(logical_and(),

bind2nd(greater(), x),

bind2nd(less(), y)));

find_if()的调用可以不显得那么复杂，只要将测试的逻辑封装入一个独立的functor(也就是申明了operator()成员函数的类)：

template

class BetweenValues:

public std::unary_function {

public:

// have the ctor save the

// values to be between

BetweenValues(const T& lowValue,

const T& highValue)

: lowVal(lowValue), highVal(highValue)

{}

// return whether val is

// between the saved values

bool operator()(const T& val) const

{

return val > lowVal && val < highVal;

}

private:

T lowVal;

T highVal;

};

...

vector iterator i =

find_if(v.begin(), v.end(),

BetweenValues(x, y));

// beginning of function

{

...

template

class BetweenValues:

public std::unary_function { ... };

vector::iterator i =

find_if(v.begin(), v.end(),

BetweenValues(x, y));

...

}

// end of function

// beginning of function

{

...

class BetweenValues:

public std::unary_function { ... };

vector iterator i =

find_if(v.begin(), v.end(),

BetweenValues(x, y));

...

}

// end of function

[1] To learn more about compose2, consult the SGI STL website () or Matt Austern’s book, Generic Programming and the STL (Addison-Wesley, 1999).

[2] Range member functions are container member functions such as insert, erase, and assign that take two iterators specifying a range to e.g., insert, erase, or assign. A single call to a range member is generally much more efficient than a hand-written loop that does the same thing. For details, consult Item 5 of Effective STL.

• 博文量
6241
• 访问量
2446639