Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

STL: Algorithms 163 In general, the more widely used a library is, the better debugged and more efficient it will be simply because it has so many users. You are unlikely to be using any other library that is as widely used as your standard library implementation. Use it and benefit. STL's algorithms are already written; why write them again? Consider trying [Boost] lambda functions. Lambda functions are an important tool that solves the biggest drawback of algorithms, namely readability: They write the function objects for you, leaving the actual code in place at the call point. Without lambda functions, your choices are to either use function objects (but then even sim- ple loop bodies live in a separate place away from the call point) or else use the standard binders and function objects such as bind2nd and plus (these are tedious and confusing to use, and hard to combine because fundamental operations like compose are not part of the standard; but do consider the [C++TR104] bind library). Examples Here are two examples adapted from [Meyers01]: Example 1: Transforming a deque. After working through several incorrect iterations that ran afoul of iterator invalidation issues (e.g., see Item 83), we finally come up with the following correct handwritten loop for adding 41 to every element of data, an array of doubles, and placing the result at the beginning of d, a deque<double>: deque<double>::iterator current = d.begin(); for( size_t i = 0; i < max; ++i ) { current = d.insert( current, data[i] + 41 ); ++current; } // be careful to keep current valid... // ... then increment it when it's safe An algorithm call would have bypassed the correctness pitfalls straight away: transform( data.begin(), data.end(), // copy elements from data inserter(d, d.begin()), // to the front of d bind2nd(plus<double>(), 41) ); // adding 41 to each Granted, bind2nd and plus are awkward. Frankly, nobody really uses them much, and that's just as well because they hurt readability (see Item 6). But lambda functions, which generate the function object for us, let us write simply: transform( data, data + max, inserter( d, d.begin() ), _1 + 41 ); Example 2: Find the first element between x and y. Consider this naked loop that searches a vector<int> v for the first value between x and y, by calculating an itera- tor that points to the found element or to v.end(): vector<int>::iterator i = v.begin(); for( ; i != v.end(); ++i ) if( *i > x && *i < y ) break;