Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a C-style function address with std::bind and std::function.target using a method from object

Tags:

c++

I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:

#include <functional>
#include <iostream>

void foo(void(*f)(int)) {
    f(2);
}

class TestClass {
    public:
        std::function<void(int)> f;
        void foo(int i) {
            std::cout << i << "\n"; 
        }

};

int main() {

    TestClass t;
    t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
    foo( t.f.target<void(int)>() );

    return 0;
}

What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:

error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
        return const_cast<_Functor*>(__func);

As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.

like image 309
Felipe Avatar asked Dec 08 '25 08:12

Felipe


1 Answers

This is a dirty little hack but should work

void foo(void(*f)(int)) {
    f(2);
}

class TestClass {
public:
    void foo(int i) {
        std::cout << i << "\n"; 
    }
};

static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
    global_variable_hack->foo(x);
}


int main() {

    TestClass t;
    global_variable_hack = &t;
    foo(hacky_function);

    return 0;
}

//can also be done with a lambda without the global stuff
int main() {
    static TestClass t;
    auto func = [](int x) {
        t->foo(x); //does not need to be captured as it is static
    };
    foo(func); //non-capturing lambas are implicitly convertible to free functions
}
like image 92
Mestkon Avatar answered Dec 10 '25 00:12

Mestkon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!