Function pointers vs boost.function

I have some code that uses pointers to member functions (not boost.function). It compiles and works fine. But when I tried to convert the code to use boost.function, I got a mess of errors. I know I'm doing something wrong, but I have no idea what it is. A clue would be greatly appreciated. Here's a reduced test case. #include <boost/function.hpp> struct X { double f(double x) { return x; } double g(double x) { return -x; } //typedef boost::function<double (double)> ftype; typedef double (X::*ftype)(double); double call(ftype func, double x) { //return func(x); return (this->*func)(x); } }; int main(int argc, char *argv[]) { X x; x.call(&X::f, 1.0); // Error occurs here x.call(&X::g, 2.0); } It compiles as it appears above, but if I switch the typedef and return statements to their commented versions, I get the following errors: if g++ -DHAVE_CONFIG_H -I. -I/home/kohler/Projects/test/trunk/src -I.. -O0 -Wall -g3 -MT test.0 -MD -MP -MF ".deps/test.Tpo" -c -o test.o /home/kohler/Projects/test/trunk/src/test.cpp; then mv -f ".deps/test.Tpo" ".deps/test.Po"; else rm -f ".deps/test.Tpo"; exit 1; fi /usr/include/boost/function/function_template.hpp: In static member function 'static R boost::detail::function::function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = boost::_mfi::mf1<double, X, double>, R = double, T0 = double]': /usr/include/boost/function/function_template.hpp:368: instantiated from 'void boost::detail::function::basic_vtable1<R, T0, Allocator>::init(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = boost::_mfi::mf1<double, X, double>, R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:298: instantiated from 'void boost::detail::function::basic_vtable1<R, T0, Allocator>::init(F) [with F = boost::_mfi::mf1<double, X, double>, R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:339: instantiated from 'void boost::detail::function::basic_vtable1<R, T0, Allocator>::init(MemberPtr, boost::detail::function::member_ptr_tag) [with MemberPtr = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:298: instantiated from 'void boost::detail::function::basic_vtable1<R, T0, Allocator>::init(F) [with F = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:277: instantiated from 'boost::detail::function::basic_vtable1<R, T0, Allocator>::basic_vtable1(F) [with F = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:655: instantiated from 'void boost::function1<R, T0, Allocator>::assign_to(Functor) [with Functor = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:513: instantiated from 'boost::function1<R, T0, Allocator>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:753: instantiated from 'boost::function<R ()(T0), Allocator>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = double (X::*)(double), R = double, T0 = double, Allocator = std::allocator<void>]' /home/kohler/Projects/test/trunk/src/test.cpp:21: instantiated from here /usr/include/boost/function/function_template.hpp:134: error: no match for call to '(boost::_mfi::mf1<double, X, double>) (double&)' /usr/include/boost/bind/mem_fn_template.hpp:160: note: candidates are: R boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R = double, T = X, A1 = double] /usr/include/boost/bind/mem_fn_template.hpp:179: note: R boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R = double, T = X, A1 = double] g++ -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)

On Tue, Sep 2, 2008 at 14:53, Kurt Kohler <kohler@ao.com> wrote:
struct X { double f(double x) { return x; }
typedef boost::function<double (double)> ftype;
double call(ftype func, double x);
};
int main(int argc, char *argv[]) { X x; x.call(&X::f, 1.0); // Error occurs here }
&X::f requires 2 arguments (the this pointer and the function argument), so it's storable in a boost::function<double(X*const, double)>. Presumably you want this instead: x.call( bind(&X::f, x, _1), 1.0 ); HTH, ~ Scott

AMDG Kurt Kohler wrote:
I have some code that uses pointers to member functions (not boost.function). It compiles and works fine. But when I tried to convert the code to use boost.function, I got a mess of errors. I know I'm doing something wrong, but I have no idea what it is. A clue would be greatly appreciated.
When you use Boost.Function with member functions, you need to pass "this" as the first argument. #include <boost/function.hpp> struct X { double f(double x) { return x; } double g(double x) { return -x; } typedef boost::function<double(X*, double)> ftype; double call(ftype func, double x) { return func(this, x); } }; int main(int argc, char *argv[]) { X x; x.call(&X::f, 1.0); x.call(&X::g, 2.0); } In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Kurt Kohler wrote:
I have some code that uses pointers to member functions (not boost.function). It compiles and works fine. But when I tried to convert the code to use boost.function, I got a mess of errors. I know I'm doing something wrong, but I have no idea what it is. A clue would be greatly appreciated.
When you use Boost.Function with member functions, you need to pass "this" as the first argument.
#include <boost/function.hpp>
struct X { double f(double x) { return x; } double g(double x) { return -x; }
typedef boost::function<double(X*, double)> ftype; double call(ftype func, double x) { return func(this, x); } };
int main(int argc, char *argv[]) { X x; x.call(&X::f, 1.0); x.call(&X::g, 2.0); } The test case now compiles! I made the corresponding change to the real code and that compiles as well.
Thanks a lot!
participants (3)
-
Kurt Kohler
-
Scott McMurray
-
Steven Watanabe