The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science

Programming Languages and Tools:

CS:3210:0001

Lecture/Lab #27

Programming with C++

Generic algorithms (cont.), inserter/stream iterators, lambda expressions

Generic algorithms (recap)

  • Operate on iterators/iterator ranges, are independent of any particular container type. 
  • Do impose certain requirements on the element type (e.g. presence of operator ==)
  • 100+ algorithms following a consistent architecture / set of patterns:
  • operate over a range of elements, typically the first two parameters are iterators that denote the input range
  • can modify elements in the containers, do not modify the container itself
  • special iterators exist that allow for other side-effects, including modification of containers

Special iterators (<iterator> header)

std::back_inserter( c )

Returns a "back inserter" iterator for c, which appends to the end of c when the iterator is dereferenced and consequently assigned to.

std::front_inserter( c )

Returns a "front inserter" iterator for c, which appends to the beginning of c when the iterator is dereferenced and consequently assigned to.

std::inserter( c, pos )

Returns an "inserter" iterator for c, which inserts elements into c at the position pos when the iterator is dereferenced and consequently assigned to.

std::ostream_iterator<T>(stream, " ")

Returns an output iterator that writes objects of type T into stream using operator<<

std::istream_iterator<T>(stream)

Returns an input iterator that reads objects of type T from stream using operator>>

Algorithms with predicates

auto i = find_if( first, last, p );

Returns an iterator to the first element for which predicate p returns true.

auto n = count_if( first, last, p );

Returns the number of elements for which predicate p returns true.

auto i = copy_if( first, last, dest, p );

Copies elements in the range for which predicate p returns true to another range beginning at dest.

replace_if( first, last, p, newv );

Replaces all elements for which predicate p returns true with newv.

auto i = remove_if( first, last, p );

Removes all elements for which predicate p returns true, returns a past-the-end iterator for the new range of values.

auto b = all_of( first, last, p );

Returns true if predicate p returns true for all elements in the range

auto b = any_of( first, last, p );

Returns true if predicate p returns true for at least one  element in the range

auto b = none_of( first, last, p );

Returns true if predicate p returns true for no elements in the range

Lambda expressions

A convenient way to define an anonymous function object at the point of use

std::vector<int> v = { 11, 22, 33, 44, 55, 66, 77 };
auto iter = std::find_if( v.begin(), v.end(), []( int n ) {
    return n > 42;
} );
  • The [] syntax actually serves a purpose and is called a capture clause.

  • The empty brackets indicate that the expression body of doesn't accesses variables from the enclosing scope.

  • Use [=] to enable capturing all outside variables by value, [&] to capture by reference.

  • Beware of lifetime issues if/when passing/returning lambda from a function.

Made with Slides.com