[Proposal] A little reasonable modification of boost::bind_t

Hi, everyone, I'd like to propose a little modification of boost:: bind to expose more information in boost:: _bi:: bind_t. Here is my motivation problem. Suppose this is a function which takes boost: :_bi::bind_t as a parameter. But at the same time, I'd like to enumerate all binded parameters and do something for specific types, like the following pseudo code shows. template< class F> void foo(F & f) { foreach(T& arg, f.arguments()) { if(boost::is_same<T, ID_t>::value) //here ID_t is a user specific type //do something for arg. } } I found that all binded arguments are stored in a listN object. But unfortunately, the list object (L _l in boost::_bi::bind_t) is set to private access and there is no method to boost::_bi::bind_t to access the listN object and the type of listN. I don't know why you developers didn't provide a method to access the listN object. But it seems reasonable to provide a public method in <boost\bind\bind_template.hpp>, like this typedef L argu_type; const L & arguments() const {return l_;} Also, the class "template<class T> class value" in <boost\bind.hpp> doesn't provide any access to T. It will be reasonable to add access of type T, like this public: typedef T val_type; With such modifications, we can access all binded arguments in the boost::_bi::bind_t. Here is a showcase. template<class T, class VT>void Test(VT t, T * p = 0) { //This parameter is not binded, so ignore it! }template<class T, class VT>void Test(VT t, typename T::val_type * p = 0) { //T::val_type is the parameter's type, //and can use boost::is_same<T::val_type, ID_t>::value to check it! std::cout<<"great! we get a value here!"<<t.get()<<std::endl; } template <class R, class F, class A1, class A2>void retrive_args(boost::_bi::bind_t<R, F, boost::_bi::list2<A1, A2> > & f) { Test<A1>(f.arguments()[_1]); Test<A2>(f.arguments()[_2]); } int f(int a, double b) { std::cout<<a<<std::endl; return a; } int main(int argc, char * argv[]) { double t = 1.0; retrive_args(boost::bind(f, _1, 0.2)); //Here will retrive the second parameters only. return 0; } I don't know if I get the right way to implement it. Please let me know if you have another implementation. Any comments or ideas will be appreciated. Thanks. -- Athrun Arthur Cluster and Grid Computing Lab (CGCL) Services Computing Technology and System Lab (SCTS) School of Computer Science and Technology (CS) Huazhong University of Science and Technology (HUST) Wuhan, 430074, China EMail:athrunarthur@gmail.com

On 11/05/13 08:52, Arthur Athrun wrote:
Hi, everyone,
I'd like to propose a little modification of boost:: bind to expose more information in boost:: _bi:: bind_t.
Here is my motivation problem. Suppose this is a function which takes boost: :_bi::bind_t as a parameter. But at the same time, I'd like to enumerate all binded parameters and do something for specific types, like the following pseudo code shows.
template< class F> void foo(F & f) { foreach(T& arg, f.arguments()) { if(boost::is_same<T, ID_t>::value) //here ID_t is a user specific type //do something for arg. } }
A polymorphic function object does not have a single type for the arguments nor even a single arity.

2013/5/11 Arthur Athrun <athrunarthur@gmail.com>:
Hi, everyone,
I'd like to propose a little modification of boost:: bind to expose more information in boost:: _bi:: bind_t. <...> With such modifications, we can access all binded arguments in the boost::_bi::bind_t. Here is a showcase.
template<class T, class VT>void Test(VT t, T * p = 0) { //This parameter is not binded, so ignore it! }template<class T, class VT>void Test(VT t, typename T::val_type * p = 0) { //T::val_type is the parameter's type, //and can use boost::is_same<T::val_type, ID_t>::value to check it! std::cout<<"great! we get a value here!"<<t.get()<<std::endl; }
template <class R, class F, class A1, class A2>void retrive_args(boost::_bi::bind_t<R, F, boost::_bi::list2<A1, A2> > & f) { Test<A1>(f.arguments()[_1]); Test<A2>(f.arguments()[_2]); }
int f(int a, double b) { std::cout<<a<<std::endl; return a; }
int main(int argc, char * argv[]) { double t = 1.0; retrive_args(boost::bind(f, _1, 0.2)); //Here will retrive the second parameters only. return 0; }
I don't know if I get the right way to implement it. Please let me know if you have another implementation. Any comments or ideas will be appreciated. Thanks.
Simpler solution would be to use boost::tuple or boost::fusion::vector to store and pass parameters separetly from function. Only after all the work with parameters done, call boost::bind and retrieve your functional object. -- Best regards, Antony Polukhin

On May 11, 2013 12:59 AM, "Arthur Athrun" <athrunarthur@gmail.com> wrote:
Hi, everyone,
I'd like to propose a little modification of boost:: bind to expose more information in boost:: _bi:: bind_t.
Here is my motivation problem. Suppose this is a function which takes
boost:
:_bi::bind_t as a parameter. But at the same time, I'd like to enumerate all binded parameters and do something for specific types, like the following pseudo code shows.
template< class F> void foo(F & f) { foreach(T& arg, f.arguments()) { if(boost::is_same<T, ID_t>::value) //here ID_t is a user specific type //do something for arg. } }
I found that all binded arguments are stored in a listN object. But unfortunately, the list object (L _l in boost::_bi::bind_t) is set to private access and there is no method to boost::_bi::bind_t to access the listN object and the type of listN.
I don't know why you developers didn't provide a method to access the listN object. But it seems reasonable to provide a public method in <boost\bind\bind_template.hpp>, like this
typedef L argu_type;
const L & arguments() const {return l_;}
Also, the class "template<class T> class value" in <boost\bind.hpp> doesn't provide any access to T. It will be reasonable to add access of type T, like this
public: typedef T val_type;
With such modifications, we can access all binded arguments in the boost::_bi::bind_t. Here is a showcase.
template<class T, class VT>void Test(VT t, T * p = 0) { //This parameter is not binded, so ignore it! }template<class T, class VT>void Test(VT t, typename T::val_type * p = 0) { //T::val_type is the parameter's type, //and can use boost::is_same<T::val_type, ID_t>::value to check it! std::cout<<"great! we get a value here!"<<t.get()<<std::endl; }
template <class R, class F, class A1, class A2>void retrive_args(boost::_bi::bind_t<R, F, boost::_bi::list2<A1, A2> > & f) { Test<A1>(f.arguments()[_1]); Test<A2>(f.arguments()[_2]); }
int f(int a, double b) { std::cout<<a<<std::endl; return a; }
int main(int argc, char * argv[]) { double t = 1.0; retrive_args(boost::bind(f, _1, 0.2)); //Here will retrive the second parameters only. return 0; }
I don't know if I get the right way to implement it. Please let me know if you have another implementation. Any comments or ideas will be appreciated. Thanks.
Sounds like something that might already be possible with Boost.Phoenix...?
participants (4)
-
Antony Polukhin
-
Arthur Athrun
-
Jeffrey Lee Hellrung, Jr.
-
Mathias Gaunard