[bind] recursively binding higher-order functional objects fails to compile.

Sorry about the poor title, it is difficult for me to explain the problem without code so here is a really simple example of what i'm trying to achieve but fails to compile with Boost.Bind: #include <boost/bind.hpp> struct FunFn { typedef void result_type; template < typename Fun > void operator()(Fun fn) const { fn(); } } const Fn; void g() { std::cout << "hello\n"; } int main() { using namespace boost; bind(Fn, bind(Fn, bind(Fn, bind(Fn, ... bind(Fn, g))(); } I get type deduction errors, however i have found workaround using Boost.Function for the time being: #include <boost/function.hpp> ... boost::function< void () > fnN = bind(Fn, g), fnN-1 = bind(Fn, fnN), ..., fn1 = bind(Fn, fn2), fn = bind(Fn, fn1); bind(Fn, fn)();

From: Korcan Hussein Sent: 20 February 2008 15:06 To: boost@lists.boost.org Subject: [boost] [bind] recursively binding higher-order functional objects fails to compile.
Sorry about the poor title, it is difficult for me to explain the problem without code so here is a really simple example of what i'm trying to achieve but fails to compile with Boost.Bind:
#include <boost/bind.hpp>
struct FunFn {
typedef void result_type; template < typename Fun > void operator()(Fun fn) const { fn(); }
} const Fn;
void g() { std::cout << "hello\n"; }
int main() { using namespace boost;
bind(Fn, bind(Fn, bind(Fn, bind(Fn, ... bind(Fn, g))();
Clearly: bind(Fn,g)(); works. What about: bind(Fn, bind(Fn, g))(); If that works, how many binds can you add before it stops working?
}
I get type deduction errors,
You may have run into a compiler limit. What compiler are you using?
however i have found workaround using Boost.Function for the time being:
#include <boost/function.hpp>
... boost::function< void () > fnN = bind(Fn, g), fnN-1 = bind(Fn, fnN), ..., fn1 = bind(Fn, fn2), fn = bind(Fn, fn1);
bind(Fn, fn)();
-- Martin Bonner Senior Software Engineer/Team Leader PI SHURLOK LTD Telephone: +44 1223 441434 / 203894 (direct) Fax: +44 1223 203999 Email: martin.bonner@pi-shurlok.com www.pi-shurlok.com disclaimer

Martin Bonner wrote:
Clearly: bind(Fn,g)(); works. What about:
bind(Fn, bind(Fn, g))();
If that works, how many binds can you add before it stops working?
Yep just the very first bind works but no more levels compile.
You may have run into a compiler limit. What compiler are you using?
I've tried this with VC++ 8.0 & VC++ 9.0 so far. Actually I'm not sure my workaround using Boost.Function is actually equivalent to what i'm trying to achieve.

AMDG Korcan Hussein wrote:
Sorry about the poor title, it is difficult for me to explain the problem without code so here is a really simple example of what i'm trying to achieve but fails to compile with Boost.Bind:
#include <boost/bind.hpp>
struct FunFn {
typedef void result_type; template < typename Fun > void operator()(Fun fn) const { fn(); }
} const Fn;
void g() { std::cout << "hello\n"; }
int main() { using namespace boost;
bind(Fn, bind(Fn, bind(Fn, bind(Fn, ... bind(Fn, g))();
}
This creates a function object that executes: Fn(Fn(Fn(g()))) Since the inner functions return void, of course it fails.
I get type deduction errors, however i have found workaround using Boost.Function for the time being:
#include <boost/function.hpp>
... boost::function< void () > fnN = bind(Fn, g), fnN-1 = bind(Fn, fnN), ..., fn1 = bind(Fn, fn2), fn = bind(Fn, fn1);
bind(Fn, fn)();
In Christ, Steven Watanabe

Korcan Hussein wrote:
Steven Watanabe wrote: This creates a function object that executes:
Fn(Fn(Fn(g())))
Since the inner functions return void, of course it fails.
Oops, this isn't exactly what i'm trying to achieve, i just want bind/pass but not evalute.
You need to use `protect()` to prevent bind() from eagerly evaluating nested binds. See: http://www.boost.org/libs/bind/bind.html#nested_binds -- Daniel Wallin Boost Consulting www.boost-consulting.com

Daniel Wallin wrote:
Korcan Hussein wrote:
Steven Watanabe wrote: This creates a function object that executes:
Fn(Fn(Fn(g())))
Since the inner functions return void, of course it fails.
Oops, this isn't exactly what i'm trying to achieve, i just want bind/pass but not evalute.
You need to use `protect()` to prevent bind() from eagerly evaluating nested binds. See: http://www.boost.org/libs/bind/bind.html#nested_binds
I was looking for something like this, great thanks a lot.
participants (4)
-
Daniel Wallin
-
Korcan Hussein
-
Martin Bonner
-
Steven Watanabe