Boost Lamdba: Binding to overloaded operator and templated functions???

Is it possible to bind to the following functions using boost.lamdba and if so how? class some_class { public: some_class operator % (int x) { return this } template<typename T> void foo(T x){ } }; I use the examples given in online-documentation but it gives me a lot of errors. I'm using VC8 on windows XP. Thanks, Haroon

On Nov 28, 2006, at 10:44 PM, Haroon Khan wrote:
Is it possible to bind to the following functions using boost.lamdba and if so how?
class some_class { public: some_class operator % (int x) { return this }
template<typename T> void foo(T x){ } };
I use the examples given in online-documentation but it gives me a lot of errors. I'm using VC8 on windows XP.
Not exactly sure what you are after but here are a few valid ways: some_class s; int i; ret<some_class>(var(s) % _1)(i); bind(&some_class::operator%, var(s), _1)(i); bind(&some_class::operator%, &s, _1)(i); bind(&some_class::foo<int>, var(s), _1)(i); bind(&some_class::foo<int>, &s, _1)(i); Cheers, Jaakko
Thanks, Haroon _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Jaakko, Thanks for your reply, I tried some of your suggestions and they are still giving me compile errors. Here is some code that Ive been playing with. This was compiled in VC8. struct some_functor { private: int x_; public: template<typename SOMETYPE> some_functor& template_foo(SOMETYPE x){ std::cout<<boost::format("Calling %x.%s(%d)\n") % this % __FUNCTION__%x; return *this; } }; void test16 { PRINT_FUNCTION_NAME; using namespace boost::lambda; int a[] = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<int> v(a, a+sizeof(a)/sizeof(int)); (bind(&(some_functor::template_foo<int>), some_functor(), _1))(boost::cref(1)) } The error that I'm getting is as follows. From the error information, it seems that it cant seem to find the right template of bind to instantiate. It starts to from arity 10 through arity 1. This also ties in with my question in an earlier post of using boost::format in a lambda expression. The overloaded operator in the basic_format class in the boost.format library is a template overloaded operator. 1>c:\haroon\dev\testprograms\lambda\lambda.cpp(461) : error C2780: 'const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<10,boost::lambda::function_action<10,T>>,detail::bind_tuple_mapper<const Arg1,const Arg2,const Arg3,const Arg4,const Arg5,const Arg6,const Arg7,const Arg8,const Arg9,const Arg10>::type>> boost::lambda::bind(const Arg1 &,const Arg2 &,const Arg3 &,const Arg4 &,const Arg5 &,const Arg6 &,const Arg7 &,const Arg8 &,const Arg9 &,const Arg10 &)' : expects 10 arguments - 3 provided 1> c:\haroon\dev\libs\boost\include\boost\lambda\detail\bind_functions.hpp(1743) : see declaration of 'boost::lambda::bind' 1>c:\haroon\dev\testprograms\lambda\lambda.cpp(461) : error C2780: 'const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<Arity,Act>,detail::bind_tuple_mapper<const Arg1,const Arg2,const Arg3,const Arg4,const Arg5,const Arg6,const Arg7,const Arg8,const Arg9,const Arg10>::type>> boost::lambda::bind(const Arg1 &,const Arg2 &,const Arg3 &,const Arg4 &,const Arg5 &,const Arg6 &,const Arg7 &,const Arg8 &,const Arg9 &,const Arg10 &)' : expects 10 arguments - 3 provided 1> with 1> [ 1> Arity=10, 1> Act=boost::lambda::function_action<10> 1> ] 1> c:\haroon\dev\libs\boost\include\boost\lambda\detail\bind_functions.hpp(1710) : see declaration of 'boost::lambda::bind' More errors On 11/29/06, Jaakko Järvi <jarvi@cs.tamu.edu> wrote:
On Nov 28, 2006, at 10:44 PM, Haroon Khan wrote:
Is it possible to bind to the following functions using boost.lamdba and if so how?
class some_class { public: some_class operator % (int x) { return this }
template<typename T> void foo(T x){ } };
I use the examples given in online-documentation but it gives me a lot of errors. I'm using VC8 on windows XP.
Not exactly sure what you are after but here are a few valid ways:
some_class s; int i; ret<some_class>(var(s) % _1)(i); bind(&some_class::operator%, var(s), _1)(i); bind(&some_class::operator%, &s, _1)(i); bind(&some_class::foo<int>, var(s), _1)(i); bind(&some_class::foo<int>, &s, _1)(i);
Cheers, Jaakko
Thanks, Haroon _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hello Haroon, On Nov 30, 2006, at 12:37 AM, Haroon Khan wrote:
Jaakko, Thanks for your reply, I tried some of your suggestions and they are still giving me compile errors. Here is some code that Ive been playing with. This was compiled in VC8.
struct some_functor { private: int x_; public: template<typename SOMETYPE> some_functor& template_foo(SOMETYPE x){ std::cout<<boost::format("Calling %x.%s(%d)\n") % this % __FUNCTION__%x; return *this; } };
void test16 { PRINT_FUNCTION_NAME; using namespace boost::lambda; int a[] = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<int> v(a, a+sizeof(a)/sizeof(int));
(bind(&(some_functor::template_foo<int>), some_functor(), _1))(boost::cref(1))
The arguments given to bind at the time of call to bind (e.g. some_functor) are stored as const copies. Thus some_functor will be const, and when the functor is called, you are trying to call a non-const member with a const object. Here's one way to fix it: some_functor s; (bind(&some_functor::template_foo<int>, boost::ref(s), _1))(boost::cref(1)); Cheers, Jaakko

Hi, I tried the suggestion to call a template member function as follows, some_functor s; (bind(&some_functor::template_foo<int>, boost::ref(s), _1))(boost::cref(1)); and it simply would not compile. The compiler woulds always choke on the some_functor::template_foo<int>. The only thing I could get to compile was using a typedef as follows typedef void (another_functor::*foo_int) (int) ; foo_int ptr_to_fun = &another_functor::foo<int>; some_functor f; const some_functor &reff = f; int x(1); bind(ptr_to_fun, reff, _1); // This compiles Unfortunately , this was'nt enough because everytime I tried calling the bound function like bind(ptr_to_fun, reff, _1)(x); // <- This does not compile The compiler would choke again, saying that none of the overloaded apply functions would apply. The error is as follows error C2665: 'boost::lambda::function_adaptor<Func>::apply' : none of the 2 overloads could convert all the argument types 1> with 1> [ 1> Func=void (__thiscall another_functor::* )(int) 1> ] Finally my only work around was to wrap the call to the member template function in another functor like the code snipped as follows, and then using the bound function on it. template<typename T> struct local_struct { void operator()(T x) { another_functor().foo<T>(x); } }; and then binding to the overloaded operator () as follows bind(&(local_struct<int>::operator()), boost::ref(local_struct<int>()), _1) (x); bind(&(local_struct<std::string>::operator()), boost::ref(local_struct<std::string>()), _1) ( boost::cref(std::string("This is another bind call")) ); Its interesting that the compile time problems don't occur for free template functions. I'm completely at a loss to explain why those compile errors are occuring for member template functions, even though all arguments are being passed by const reference. The complete code listing is below for reference . Thanks, Haroon struct another_functor{ template<typename T> void foo(T x) ; template<typename T> void bar(){ std::cout<< (boost::format("Return Type is %s in %s\n") % typeid(T).name() %__FUNCTION__).str(); } }; template<> void another_functor::foo<int>(int x) { std::cout<< (boost::format("%s(%d)\n") % __FUNCTION__ % x).str(); } template<> void another_functor::foo(float x) { std::cout<<(boost::format("%s(%f)\n")%__FUNCTION__%x).str(); } template<> void another_functor::foo(std::string x) { std::cout<<(boost::format("%s(\"%s\")\n")%__FUNCTION__%x).str(); } template<typename T> void free_func(T x){ std::cout<<__FUNCTION__<<"("<<x<<")"<<std::endl; } template<typename T> struct local_struct { void operator()(T x) { another_functor().foo<T>(x); } }; void test17() { PRINT_FUNCTION_NAME; another_functor().foo<std::string>(std::string("Calling the string function")); another_functor().foo<float>(1.32f); another_functor().foo<int>(1); another_functor().bar<int>(); another_functor().bar<std::list<int> >(); using namespace boost::lambda; std::cout<<typeid(free_func<int>).name()<<std::endl; bind(free_func<int>, _1)(boost::cref(1)); typedef void (another_functor::*foo_int) (int) ; foo_int ptr_to_fun = &another_functor::foo<int>; some_functor f; const some_functor &reff = f; int x(1); bind(ptr_to_fun, reff, _1); // This compiles //bind(ptr_to_fun, reff, _1)(x); // <- This does not compile typedef void (another_functor::*bar_int) (); bar_int ptr_to_bar = &another_functor::bar<int>; bind(ptr_to_bar, reff); // Compiles !!! //bind(ptr_to_bar, reff)(); // Does not compile //The only work-around I could think of bind(&(local_struct<int>::operator()), boost::ref(local_struct<int>()), _1) (x); bind(&(local_struct<std::string>::operator()), boost::ref(local_struct<std::string>()), _1) ( boost::cref(std::string("This is another bind call")) ); } On 11/30/06, Jaakko Järvi <jarvi@cs.tamu.edu> wrote:
Hello Haroon,
On Nov 30, 2006, at 12:37 AM, Haroon Khan wrote:
Jaakko, Thanks for your reply, I tried some of your suggestions and they are still giving me compile errors. Here is some code that Ive been playing with. This was compiled in VC8.
struct some_functor { private: int x_; public: template<typename SOMETYPE> some_functor& template_foo(SOMETYPE x){ std::cout<<boost::format("Calling %x.%s(%d)\n") % this % __FUNCTION__%x; return *this; } };
void test16 { PRINT_FUNCTION_NAME; using namespace boost::lambda; int a[] = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<int> v(a, a+sizeof(a)/sizeof(int));
(bind(&(some_functor::template_foo<int>), some_functor(), _1))(boost::cref(1))
The arguments given to bind at the time of call to bind (e.g. some_functor) are stored as const copies. Thus some_functor will be const, and when the functor is called, you are trying to call a non-const member with a const object.
Here's one way to fix it:
some_functor s; (bind(&some_functor::template_foo<int>, boost::ref(s), _1))(boost::cref(1));
Cheers, Jaakko
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Haroon Khan
-
Jaakko Järvi