Re: [boost] [Bind] How do I get bind to deduce the return type of for_each?

Thomas Jordan wrote:
Hi, I have been trying to use Boost.bind to create an 'STL algorithm function object' to pass into another, 'higher order,' STL algorithm (e.g., to pass a for_each into a for_each). However, I am struggling to get bind to deduce the correct return type of the for_each function object. I include the relevant bits of the code below.
class myClass { public: int func(){return mValue;} private: int mValue; };
//wrapper for STL for_each struct myForEach { template <typename II, typename F> F operator()(II begin, II end, F function) const { return std::for_each(begin, end, function); } };
typedef vector<myClass> vocType; typedef vector<vocType> vovType;
//overloaded member functions vocType::begin & end typedef vocType::iterator (vocType::*fnPtr)(); typedef const vocType::iterator (vocType::*constFnPtr)() const;
vovType vov(10, vocType(10, myClass()));
main() { for_each(vov.begin(), vov.end(), bind< ? >(myForEach(), bind(static_cast<fnPtr>(&vocType::begin),_1), bind(static_cast<fnPtr>(&vocType::end),_1), protect(bind(&myClass::func, _1))) }
I tried various things for bind<?>, but was only able to get the code to compile (eventually) on my Unix box when I substituted bind< boost::_bi::protected_bind_t<boost::_bi::bind_t<int, boost::_mfi::mf0<int, myClass>, boost::_bi::list1<boost::arg<1> (*)()> > > > for the bind<?>. I had guessed this might work from studying the compiler error messages. Obviously, this is not an ideal solution!
Also, I only used the myForEach wrapper after having first attempted - and similarly failed - to bind the raw STL for_each.
Is there any way I can help bind to deduce the correct return type - for either myForEach or std::for_each, or both?
--Roland Bock wrote------------------------------------------------------------------ In my experience it is easier to use a named functor object. Such as function<void (const vocType&)> functor = bind(&myClass::func, _1); std::for_each(vov.begin(), vov.end(), functor); Untested, but I am pretty sure something along these lines will work. Regards, Roland ------------------------------------------------------------------------------------------------- Thanks for the suggestion, Roland, I am sure you could get something like this to work easily enough. However, if I understand correctly your suggestion involves defining a separate functor - myClass - to take the vocType's, and which I guess wraps the inner call to for_each. I had hoped for a more generic solution which doesn't involve the creation of new functors. I was hoping I could accomplish the objective of passing an algorithm into an algorithm jgenerically, just doing everything at point of call using just Boost.bind, the std::algorithms (wrapped) and using if necessary some boost.function functors to help type deduction. Are we saying this isn't possible?

Thomas Jordan wrote:
[snip] Thanks for the suggestion, Roland, I am sure you could get something like this to work easily enough. However, if I understand correctly your suggestion involves defining a separate functor - myClass - to take the vocType's, and which I guess wraps the inner call to for_each. I had hoped for a more generic solution which doesn't involve the creation of new functors. I was hoping I could accomplish the objective of passing an algorithm into an algorithm jgenerically, just doing everything at point of call using just Boost.bind, the std::algorithms (wrapped) and using if necessary some boost.function functors to help type deduction. Are we saying this isn't possible?
Hi Thomas, we don't say it isn't possible :-) Here you go: // ----------------------------------------------------------- #include <boost/bind.hpp> #include <boost/bind/protect.hpp> #include <boost/function.hpp> #include <vector> #include <iostream> using namespace std; using namespace boost; int initValue = 0; class myClass { public: myClass(): mValue(initValue) {} myClass(const myClass& rhs): mValue(initValue++) { } void func() { cout << mValue << endl; } private: int mValue; }; typedef vector<myClass> vocType; typedef vector<vocType> vovType; int main() { vovType vov(10, vocType(10, myClass())); for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) ); } // ----------------------------------------------------------- Please let me know if this is working for you. Regards, Roland

On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote:
Thomas Jordan wrote:
[snip] Thanks for the suggestion, Roland, I am sure you could get something like this to work easily enough. However, if I understand correctly your suggestion involves defining a separate functor - myClass - to take the vocType's, and which I guess wraps the inner call to for_each. I had hoped for a more generic solution which doesn't involve the creation of new functors. I was hoping I could accomplish the objective of passing an algorithm into an algorithm jgenerically, just doing everything at point of call using just Boost.bind, the std::algorithms (wrapped) and using if necessary some boost.function functors to help type deduction. Are we saying this isn't possible?
Hi Thomas,
we don't say it isn't possible :-)
Here you go:
<snip>
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones. Daniel Walker

Daniel Walker wrote:
On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote:
Thomas Jordan wrote:
[snip] Thanks for the suggestion, Roland, I am sure you could get something like this to work easily enough. However, if I understand correctly your suggestion involves defining a separate functor - myClass - to take the vocType's, and which I guess wraps the inner call to for_each. I had hoped for a more generic solution which doesn't involve the creation of new functors. I was hoping I could accomplish the objective of passing an algorithm into an algorithm jgenerically, just doing everything at point of call using just Boost.bind, the std::algorithms (wrapped) and using if necessary some boost.function functors to help type deduction. Are we saying this isn't possible?
Hi Thomas,
we don't say it isn't possible :-)
Here you go:
<snip>
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones.
Daniel Walker
Thanks :-) Btw, could I do the same with tr1::bind? What would be the equivalent of boost::protect? Regards, Roland

On Sat, Apr 17, 2010 at 8:58 AM, Roland Bock <rbock@eudoxos.de> wrote:
Daniel Walker wrote:
On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote:
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones.
Daniel Walker
Thanks :-)
Btw, could I do the same with tr1::bind? What would be the equivalent of boost::protect?
Yeah, you can do the same thing in TR1. Instead of boost::protect, you can just use tr1::function, again. :) for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), function<void(myClass&)>(bind(&myClass::func, _1)) ) ); Actually, I once wrote a functional_cast (analogous to lexical_cast) that did something like that. It's in vault. Daniel Walker

Daniel Walker wrote:
On Sat, Apr 17, 2010 at 8:58 AM, Roland Bock <rbock@eudoxos.de> wrote:
Daniel Walker wrote:
On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote:
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones.
Daniel Walker
Thanks :-)
Btw, could I do the same with tr1::bind? What would be the equivalent of boost::protect?
Yeah, you can do the same thing in TR1. Instead of boost::protect, you can just use tr1::function, again. :)
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), function<void(myClass&)>(bind(&myClass::func, _1)) ) );
Actually, I once wrote a functional_cast (analogous to lexical_cast) that did something like that. It's in vault.
Daniel Walker
OK, got it, the function object kind of digests the inner _1 before the outer bind can lay its fingers on it :-) Just took a look at the polymorphic_function and functional_cast. I'll have to try and remember it, because I am sure I had use cases for that in the past (obviously solved them in another way). How would you apply them to the current topic? Regards, Roland

On Sat, Apr 17, 2010 at 11:50 AM, Roland Bock <rbock@eudoxos.de> wrote:
Daniel Walker wrote:
On Sat, Apr 17, 2010 at 8:58 AM, Roland Bock <rbock@eudoxos.de> wrote:
Daniel Walker wrote:
On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote:
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones.
Daniel Walker
Thanks :-)
Btw, could I do the same with tr1::bind? What would be the equivalent of boost::protect?
Yeah, you can do the same thing in TR1. Instead of boost::protect, you can just use tr1::function, again. :)
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), function<void(myClass&)>(bind(&myClass::func, _1)) ) );
Actually, I once wrote a functional_cast (analogous to lexical_cast) that did something like that. It's in vault.
Daniel Walker
OK, got it, the function object kind of digests the inner _1 before the outer bind can lay its fingers on it :-)
Exactly. :) And moreover, with respect to TR1/c++0x, is_bind_expression has not been specialized for the function object's type, so it's not treated as a sub-bind expression.
Just took a look at the polymorphic_function and functional_cast. I'll have to try and remember it, because I am sure I had use cases for that in the past (obviously solved them in another way). How would you apply them to the current topic?
Oh, I was just mentioning it as an aside, because the idiom looks similar; e.g. wrapping things with function<signature>(object). functional_cast can be used to change the signature in order to achieve a polymorphic effect when the underling object can support multiple call signatures. But that's not the issue here. Daniel Walker

On Sat, Apr 17, 2010 at 1:30 PM, Daniel Walker <daniel.j.walker@gmail.com>wrote:
Thomas Jordan wrote:
[snip] Thanks for the suggestion, Roland, I am sure you could get something
On Sat, Apr 17, 2010 at 7:25 AM, Roland Bock <rbock@eudoxos.de> wrote: like
this to work easily enough. However, if I understand correctly your suggestion involves defining a separate functor - myClass - to take the vocType's, and which I guess wraps the inner call to for_each. I had hoped for a more generic solution which doesn't involve the creation of new functors. I was hoping I could accomplish the objective of passing an algorithm into an algorithm jgenerically, just doing everything at point of call using just Boost.bind, the std::algorithms (wrapped) and using if necessary some boost.function functors to help type deduction. Are we saying this isn't possible?
Hi Thomas,
we don't say it isn't possible :-)
Here you go:
<snip>
for_each(vov.begin(), vov.end(), bind(for_each< vocType::iterator, function<void (myClass&)> >, bind<vocType::iterator>(&vocType::begin, _1), bind<vocType::iterator>(&vocType::end, _1), protect(bind(&myClass::func, _1)) ) );
Oh yeah, that's a good idea! Instantiate std::for_each with a void boost::function! That's a portable solution as well, since bind and function are available on practically any compiler, even ancient, substandard ones.
Daniel Walker _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Could you do this with directory iteration too? Say to call a function for every file in every directory in the current directory. Ie., a two level tree walk, rather than a fully recursive one, but all in one statement? - Rob.

Could you do this with directory iteration too? Say to call a function for every file in every directory in the current directory. Ie., a two level tree walk, rather than a fully recursive one, but all in one statement?
- Rob.
For this problem wouldn't you just use the
boost::filesystem::recursive_directory_iterator ? It seems cleaner. However the whole notion of projections from higher dimensional spaces into sequences and ranges is something I have been looking into for some time. Once this release of Boost.Range is done, I intend to open up a broader discussion on this topic. Regards, Neil Groves

On Tue, Apr 20, 2010 at 4:57 PM, Neil Groves <neil@grovescomputing.com>wrote:
Could you do this with directory iteration too? Say to call a function
for
every file in every directory in the current directory. Ie., a two level tree walk, rather than a fully recursive one, but all in one statement?
- Rob.
For this problem wouldn't you just use the boost::filesystem::recursive_directory_iterator ? It seems cleaner.
Yes I think you would - I hadn't been aware of recursive_directory_iterator - cheers Neil. - Rob.
participants (5)
-
Daniel Walker
-
Neil Groves
-
Robert Jones
-
Roland Bock
-
Thomas Jordan