[bind][function] Newbie finds errors, but in Boost or between chair and keyboard?

Greetings, I'm a newbie, at least to Boost, and I have been playing around with it to get familiar with it, and to improve my c++ skills. :) I've run into two problems with boost::bind (and I suspect there is a connection with boost::function). The two programs at the bottom of this message demonstrate these problems. Can anybody shed a light on this? Are these errors in Boost, or did I miss something in the documentation? Should I ask on another mailing list? Or should I file a bug report? Platform: linux-x86 Compiler: GNU C++ version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) STL : GNU libstdc++ version 20061115 Boost : 1.35.0 Regards, Jeroen. ------------------------------------------------------------------------ #include <boost/bind.hpp> #include <boost/function.hpp> bool doit(int i) { return i > 0; } int main(void) { boost::function1<bool, int> mything; mything = boost::bind(doit, 3); // The statement below results in error: // bind-and-function.cpp:24: error: no match for call to // $-1òø(boost::function1<bool, int, // std::allocator<boost::function_base> >) ()$-1òù // /usr/include/boost/function/function_template.hpp:819: note: // candidates are: typename boost::function1<R, T0, // Allocator>::result_type boost::function1<R, T0, // Allocator>::operator()(T0) const [with R = bool, T0 = int, // Allocator = std::allocator<boost::function_base>] return mything() ? 0 : 1; } ------------------------------------------------------------------------ #include <boost/bind.hpp> #include <boost/function.hpp> #include <cassert> struct anything { void operator()(int var1, int var2, boost::function1<void, int>& mything) { assert(var1 == 12345); assert(var2 == 67890); mything(var1 + var2); } void one_arg(int var3, int var4) { assert(var3 == var4); } } something; int main(void) { // Building and running an expression in small steps works. boost::function1<void, int> one_arg_f = boost::bind(&anything::one_arg, &something, _1, 80235); boost::function2<void, int, int> parentheses_f = boost::bind(&anything::operator(), &something, _1, _2, one_arg_f); parentheses_f(12345, 67890); // This also works. boost::bind(&anything::operator(), &something, _1, _2, one_arg_f)(12345, 67890); // Change either zero in the preprocessor consitionals to one to // demonstrate the problem. In my setup, changing both zeroes to // ones results only in an error message for the first statement. // Leaving both zeroes in place makes this code compile and run to an // exit code of zero. #if 0 // But replacing one_arg_f by its value fails to compile: // /usr/include/boost/bind.hpp:413: error: invalid use of void // expression boost::bind(&anything::operator(), &something, _1, _2, boost::bind(&anything::one_arg, &something, _1, 80235)) (12345, 67890); #elif 0 // Separating construction and execution does not help, but shows it // is the construction that is failing. boost::function2<void, int, int> parentheses_f2 = boost::bind(&anything::operator(), &something, _1, _2, boost::bind(&anything::one_arg, &something, _1, 80235)); parentheses_f2(12345, 67890); #endif // Replacing the second _1 by _3 results in even weirder error messages. return 0; } ------------------------------------------------------------------------

AMDG Jeroen N.Witmond wrote:
int main(void) { boost::function1<bool, int> mything;
mything = boost::bind(doit, 3);
// The statement below results in error:
<snip> return mything() ? 0 : 1; }
boost::function1<bool, int> is a unary function object. You can't call it with no arguments. What you meant is probably boost::function0<bool>.
// But replacing one_arg_f by its value fails to compile: // /usr/include/boost/bind.hpp:413: error: invalid use of void // expression boost::bind(&anything::operator(), &something, _1, _2, boost::bind(&anything::one_arg, &something, _1, 80235)) (12345, 67890);
Nested binds are treated specially. The above tries to invoke: something(12345, 67890, something.one_arg(12345, 80235)); Try using protect on the inner bind: boost::protect(boost::bind(&anything::one_arg, &something, _1, 80235))) In Christ, Steven Watanabe

Steven Watanabe <watanabesj <at> gmail.com> writes:
boost::function1<bool, int> is a unary function object. You can't call it with no arguments. What you meant is probably boost::function0<bool>.
Just goes to show that I'm also a newbie in interpreting this kind of compiler error messages. :) The code I posted was an attempt at a testcase for the actual problem I had. Your answer pointed me in the right direction to solve this.
// But replacing one_arg_f by its value fails to compile: // /usr/include/boost/bind.hpp:413: error: invalid use of void // expression boost::bind(&anything::operator(), &something, _1, _2, boost::bind(&anything::one_arg, &something, _1, 80235)) (12345, 67890);
Nested binds are treated specially. The above tries to invoke: something(12345, 67890, something.one_arg(12345, 80235));
Try using protect on the inner bind: boost::protect(boost::bind(&anything::one_arg, &something, _1, 80235)))
I'll keep it in mind. Thanks for your quick and helpful reply. Jeroen.
participants (2)
-
Jeroen N. Witmond
-
Steven Watanabe