Boost logo

Boost Users :

From: Christian Rössel (christian.roessel_at_[hidden])
Date: 2006-05-18 11:55:47


Dear list,

I have a class Manager that wraps an associative container (e.g. std::map)
and that provides a method that calls a std::find_if to search on the
mapped_type.

  template <typename Func>
  boost::optional<Value&> find_if (Func func);

I want to pass free functions, functors, boost::function objects or
boost::lambda expressions to it. There is no problem with free functions
and functors but with boost::function objects (not always) and
boost::lambda expressions. The two lines that do not compile are commented
in the code below. Please find the entire error messages attached.

What am I doing wrong?

Thanks and best regards,
Christian

#include <boost/optional.hpp>
#include <boost/utility.hpp>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <algorithm>
#include <map>
#include <utility>

template <typename Key,
          typename Value,
          template <typename Key,
                    typename Value,
                    typename Compare,
                    typename Alloc> class AssocContainer,
          typename Compare = std::less<Key>,
          typename Alloc = std::allocator<std::pair<const Key, Value> >

>>

class Manager
  : public boost::noncopyable
{

public:
  typedef AssocContainer<Key, Value, Compare, Alloc> AssocCont;
  typedef Value value_type;

  Manager (const Compare& compare = Compare (),
                     const Alloc& alloc = Alloc ())
    : cont_ (compare, alloc)
  {}

  ~Manager ()
  {
    cont_.clear ();
  }

  bool insert (Key key, Value value)
  {
    return cont_.insert (std::make_pair(key, value)).second;
  }

  template <typename Func>
  boost::optional<Value&> find_if (Func func)
  {
    using boost::lambda::_1;
    using boost::lambda::bind;

    typename AssocCont::iterator findResult =
      std::find_if (cont_.begin (), cont_.end (),
                    bind(func, bind(&AssocCont::value_type::second, _1)));
    if (findResult != cont_.end()) {
      return boost::optional<Value&> (findResult->second);
    }
    return boost::optional<Value&> ();
  }

private:
  AssocCont cont_;
};

typedef Manager<char, int, std::map> Container;

bool find42function (const Container::value_type& value)
{
  return value == 42;
}

struct Find42functor
  : public std::unary_function<Container::value_type, bool>
{
  bool operator () (const Container::value_type& value) const
  {
    return value == 42;
  }
};

int
main ()
{
  Container cont;
  cont.insert ('a', 42);

  // free function -------------------------------------------------------
  cont.find_if (&find42function);

  boost::function<bool (int)> func_1 (&find42function);
  cont.find_if (func_1);

  // Functor -------------------------------------------------------------
  cont.find_if (Find42functor());

  Find42functor functor;
  boost::function<bool (int)> func_2 (functor);
  cont.find_if (func_2);

  boost::function<bool (int)> func_3 = Find42functor();
  cont.find_if (func_3);

  boost::function<bool (int)> func_4 (Find42functor());
  //cont.find_if (func_4); // does not compile
/* error message: ========================================================
/d/vendor/include/boost/lambda/detail/function_adaptors.hpp: In static
member function `static Result boost::lambda::function_adaptor<Result
(*)(Arg1)>::apply(Result (*)(Arg1), A1&) [with RET = boost::function<bool
()(int), std::allocator<void> >, A1 = int, Arg1 = Find42functor (*)(),
Result = boost::function<bool ()(int), std::allocator<void> >]':
...
test.cpp:50: instantiated from `boost::optional<Value&> Manager<Key,
Value, AssocContainer, Compare, Alloc>::find_if(Func) [with Func =
boost::function<bool ()(int), std::allocator<void> > (*)(Find42functor
(*)()), Key = char, Value = int, AssocContainer = std::map, Compare =
std::less<char>, Alloc = std::allocator<std::pair<const char, int> >]'
test.cpp:101: instantiated from here
/d/vendor/include/boost/lambda/detail/function_adaptors.hpp:218: error:
invalid conversion from `int' to `Find42functor (*)()'

see error_func_4.txt for the entire error message
========================================================================*/

  // lambda --------------------------------------------------------------
  using boost::lambda::_1;
  boost::function<bool (int)> func_5 (_1 == 42);
  cont.find_if (func_5);

  //cont.find_if (_1 == 42.0); // does not compile
/* error message: =========================================================
/d/vendor/include/boost/lambda/detail/function_adaptors.hpp: In
instantiation of
`boost::lambda::function_adaptor<bool>::sig<boost::tuples::cons<bool,
boost::tuples::cons<int, boost::tuples::null_type> > >':
...
test.cpp:50: instantiated from `boost::optional<Value&> Manager<Key,
Value, AssocContainer, Compare, Alloc>::find_if(Func) [with Func =
boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>

>>, const double, boost::tuples::null_type, boost::tuples::null_type,

boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > >, Key = char, Value
= int, AssocContainer = std::map, Compare = std::less<char>, Alloc =
std::allocator<std::pair<const char, int> >]'
test.cpp:117: instantiated from here
/d/vendor/include/boost/lambda/detail/function_adaptors.hpp:32: error:
`bool' is not a class, struct, or union type
...

See error_lambda.txt for the entire error message
========================================================================*/

  return 0;
}




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net