1

I am trying to bind a class method to a function pointer with boost::bind. I found this solution which works if no arguments are passed to the method:

convert std::bind to function pointer

I am copying also the solution for reference here:

#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <ostream>
using namespace std;

template<unsigned ID,typename Functor>
boost::optional<Functor> &get_local()
{
    static boost::optional<Functor> local;
    return local;
}

template<unsigned ID,typename Functor>
typename Functor::result_type wrapper()
{
    return get_local<ID,Functor>().get()();
}

template<typename ReturnType>
struct Func
{
    typedef ReturnType (*type)();
};

template<unsigned ID,typename Functor>
typename Func<typename Functor::result_type>::type get_wrapper(Functor f)
{
    (get_local<ID,Functor>()) = f;
    return wrapper<ID,Functor>;
}

// ----------------------------------------------------------------------

void test(void (*fptr)())
{
    fptr();
}

struct SomeStruct
{
    int data;
    void some_method()
    {
        cout << data << endl;
    }
    void another_method()
    {
        cout << -data << endl;
    }
};

int main()
{
    SomeStruct local[] = { {11} };

    test(get_wrapper<0>(  boost::bind(&SomeStruct::some_method,local[0]) ));
    test(get_wrapper<1>(  boost::bind(&SomeStruct::another_method,local[0]) ));
}

Now what I want to achieve is to change the signature of the called function to have a return type and arbitrary arguments. I tried to use boost::placeholders and changing the signature of the test method but this does not compile:

#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <ostream>
using namespace std;

template<unsigned ID,typename Functor>
boost::optional<Functor> &get_local()
{
    static boost::optional<Functor> local;
    return local;
}

template<unsigned ID,typename Functor>
typename Functor::result_type wrapper()
{
    return get_local<ID,Functor>().get()();
}

template<typename ReturnType>
struct Func
{
    typedef ReturnType (*type)();
};

template<unsigned ID,typename Functor>
typename Func<typename Functor::result_type>::type get_wrapper(Functor f)
{
    (get_local<ID,Functor>()) = f;
    return wrapper<ID,Functor>;
}

// ----------------------------------------------------------------------

void test(void (*fptr)(int ))
{
    fptr(5);
}

struct SomeStruct
{
    int data;
    void some_method(int x)
    {
        cout << data + x << endl;
    }
};

int main()
{
    SomeStruct local[] = { {11} };

    test(get_wrapper<0>(  boost::bind(&SomeStruct::some_method,local[0], boost::placeholders::_1) ));
}

To see a full error message I am providing a Link

In short, it seems that the function cannot be converted:

error: invalid conversion from 'Func<void>::type' {aka 'void (*)()'} to 'void (*)(int)' [-fpermissive]
test(get_wrapper<0>(  boost::bind(&SomeStruct::some_method,local[0], boost::placeholders::_1) ));
      |          ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                        |
      |                        Func<void>::type {aka void (*)()}

Can you guide me to a solution for this problem if possible?

RoQuOTriX
  • 2,871
  • 14
  • 25
  • Unrelated: Why not use `std::bind`? – Jason May 24 '23 at 06:42
  • @Jason I used the same code as the answer I linked. Later if my problem is solved I would try to replace boost::bind with std::bind and boost::optional with std::optional (but I had problems already on replacing boost::optional which I not further investigated, because I do not know if there is any difference between the boost::x and std::x types) – RoQuOTriX May 24 '23 at 06:44
  • Should not it be `typedef ReturnType (*type)()` --> `typedef ReturnType (*type)(int)`? – 273K May 24 '23 at 06:53
  • @273K I also though the same initially, but that will not fix the problem. – Jason May 24 '23 at 06:54
  • 2
    The linked solution does not work. It is actually not possible to convert `bind` to function pointer except when `bind` itself holds only a function pointer. It only stores functor in some static variable to access it from new function. – user7860670 May 24 '23 at 07:59

0 Answers0