1

I'm trying to achieve something with boost::bind boost::function but can't make it work.

I see how to bind a member function of an object with some arguments to be used later as a void/void function. But how to bind it to any object.

I'd like to have a pointer to a member function of my class (that could be used with any object of the class) with binded arguments:

#include "boost/function.hpp" 
#include "boost/bind.hpp" 

class A
{
public:
    A() {}

    void func1( int i );
    void func2( const std::string& s );

    static void dispatch( std::vector<A>& vect, /* boost::function parameter "func" */ ) // what parameter should I set?
    {
        for ( std::vector<A>::iterator iter = vect.begin();
              iter != vect.end();
              ++iter )
        {
            // what syntax should I use?
            //(*iter).(*func)();
        }
    }
};

int main()
{
    std::vector<A> vect;

    // have func1(3) be called for all objects contained in vect
    // this does not compile because boost expects an object to bind the function to
    A::dispatch( vect, boost::bind( boost::mem_fn(&A::func1), 3 ) );
    // have func2("hello") be called for all objects contained in vect
    // this does not compile because boost expects an object to bind the function to
    A::dispatch( vect, boost::bind( boost::mem_fn(&A::func2), "hello" ) );
}

I tried that:

static void dispatch( const std::vector<A>& vect, boost::_mfi::mf0<void, A> func )
...
boost::_mfi::mf1<void,A,int> func( boost::mem_fn(&A::func1) );
boost::_mfi::mf0<void,A> binded( boost::bind( func, 3 ) );
A::dispatch( vect, binded );

But it fails to compile:

Erreur  1   error C2664: 'boost::_mfi::mf0<R,T>::mf0(void (__thiscall A::* )(void))' : impossible de convertir le paramètre 1 de 'boost::_bi::bind_t<R,F,L>' en 'void (__thiscall A::* )(void)' b:\dev\vobs_bci\public\lib\btle\src\btle\notifierdispatcher.cpp 99

Note: I'm unfortunatley not using C++11 yet, so please no auto...;-)

Community
  • 1
  • 1
jpo38
  • 20,821
  • 10
  • 70
  • 151
  • Editing the question (to remove const) is not very classy after you got an answer. Of course, just drop `const` in various places from my answer, then – sehe Nov 12 '15 at 07:59
  • @sehe: Sorry, I was just commenting this on your answer. Itried to remove all the `const` in your code but it does not compile, reports `impossible de convertir le paramètre 2 de 'boost::_bi::bind_t' en 'boost::function &'` – jpo38 Nov 12 '15 at 08:01

1 Answers1

4

Many subtle tweaks, most simplifications:

Live On Coliru (c++03)

#include "boost/function.hpp" 
#include "boost/bind.hpp" 
#include <vector>
#include <iostream>

class A
{
public:
    A() {}

    void func1(int i) const                { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")\n"; } 
    void func2(const std::string& s) const { std::cout << __PRETTY_FUNCTION__ << "(" << s << ")\n"; } 

    static void dispatch(const std::vector<A>& vect, boost::function<void(A const&)> const& func)
    {
        for ( std::vector<A>::const_iterator iter = vect.begin();
              iter != vect.end();
              ++iter )
        {
            func(*iter);
        }
    }
};

int main()
{
    std::vector<A> vect(3);

    A::dispatch(vect, boost::bind(&A::func1, _1, 3));
    A::dispatch(vect, boost::bind(&A::func2, _1, "hello"));
}

Notes

  • Use boost::function<void(A const&)> because you dereference const iterators
  • Use A::dispatch(vect, boost::bind(&A::func1, _1, 3));
  • Mark func1 and func2 const

    void func1(int i) const;
    void func2(std::string const& i) const;
    

Output:

void a::func1(int) const(3)
void a::func1(int) const(3)
void a::func1(int) const(3)
void a::func2(const std::string &) const(hello)
void a::func2(const std::string &) const(hello)
void a::func2(const std::string &) const(hello)
user703016
  • 37,307
  • 8
  • 87
  • 112
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks sehe, this works pretty well when functions are `const`, but I can't make it work when they are not `const` (it was the case in my OP, except I was passing a const ref to the vector which was a mistake when I created my MCVE for the OP). Really sorry about that. – jpo38 Nov 12 '15 at 08:00
  • Literally just erased `const`: http://coliru.stacked-crooked.com/a/a335b444d44d6a08 (well, `const_` in the case of `iterator`) – sehe Nov 12 '15 at 08:24
  • Got it. I had other problems actually with includes (funny thing is that objects passed to the function in const reference must be defined (no forward declaration), else `boost::bind` refuses to bind. It works now. Thanks a lot for your help and sorry for the `const` ;-) – jpo38 Nov 12 '15 at 08:27
  • Well, you take _the address of a member_. It makes sense that the compiler needs to know what the class looks like – sehe Nov 12 '15 at 08:30
  • I meant function parameters (like `std::string` for `func2`). See this question I just asked: http://stackoverflow.com/questions/33667356/why-boostbind-incompatible-with-forward-declaration – jpo38 Nov 12 '15 at 08:44