Listing 9

#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
#include <iterator>
#include <ostream>
using std::tr1::array;
using std::cout; using std::basic_ostream;
using std::copy; using std::ostream_iterator;
using std::tr1::mem_fn;
using std::tr1::bind; using namespace std::tr1::placeholders;
using std::unique; using std::not2;

// comment next line out to get compile-time error
#define OKAY

struct C
  { // holds a data value
  bool eq(C c) const { return i == c.i; }
  bool neq(C c) const { return i != c.i; }
  int i;
  };

template <class Char, class Traits>
basic_ostream<Char, Traits>& operator<<(
  basic_ostream<Char, Traits>& out, const C& c)
  { // show c's stored data
  return out << c.i;
  }
typedef C elt;
typedef array<elt, 7> arr;
typedef arr::iterator arr_it;

template <class Func>
void apply(Func func)
  { // use func to eliminate duplicates in a range
  arr data = { 1, 1, 2, 3, 3, 3, 5 };
  arr_it end = unique(data.begin(), data.end(), func);
  copy(data.begin(), end, ostream_iterator<elt>(cout, " "));
  cout << '\n';
  }
int main()
  { // apply several callable objects
  apply(mem_fn(&C::eq));
  apply(not2(mem_fn(&C::neq)));
  apply(bind(&C::eq, _1, _2));
#ifndef OKAY
  apply(not2(bind(&C::neq, _1, _2)));
#endif
  return 0;
  }