Given this statement:

  // Count elements < 10: 6
count = count_if(cont1.begin(), cont1.end(), bind2nd(less<int>(), 10));
The function adapter class, less, (and base class):

Base class (binary_function), merely serves as a class to hold templated typedef's:

template<typename LeftT, typename RightT , typename ResultT>
class binary_function 
{
  public:
    typedef LeftT first_argument_type;
    typedef RightT second_argument_type;
    typedef ResultT result_type;
};
Function adapter class (less):
template <typename T>
class less : public binary_function<T, T, bool> 
{
  public:
    bool operator()(const T& a, const T &b) const
    {
      return a < b;
    }
};
Instantiating less<int>():
class less
{
  public:
    typedef int first_argument_type;
    typedef int second_argument_type;
    typedef bool result_type;
    bool operator()(const T& a, const T &b) const
    {
      return a < b;
    }
};
The count_if algorithm:

template<typename InputIt, typename Pred> inline
int count_if(InputIt first, InputIt last, Pred pred)
{
  int result = 0;
  while (first != last) 
  {
    if (pred(*first))
      ++result;
    ++first;
  }
  return result;
}
The unary function class:

template<class T, class ResultT>
struct unary_function 
{
  typedef T argument_type;
  typedef ResultT result_type;
};
The function adapter bind2nd:

template<typename BinFn>
class binder2nd : public unary_function<typename BinFn::first_argument_type, typename BinFn::result_type> 
{
  public:
    binder2nd(const BinFn& fn, const typename BinFn::second_argument_type& val): op(fn), value(val)
    {
    }

    typename BinFn::result_type operator()(const argument_type& X) const
    {
      return op(X, value); 
    }
  protected:
    BinFn op;
    typename BinFn::second_argument_type value;
};

template<typename BinFn, typename T> inline
binder2nd<BinFn> bind2nd(const BinFn& fn, const T& val)
{
  return binder2nd<BinFn>(fn, val); 
}