
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; }