|
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