using function object though function pointer is required - c++

I have to use some legacy code expecting a function pointer, let's say:
void LEGACY_CODE(int(*)(int))
{
//...
}
However the functionality I have is within a functor:
struct X
{
Y member;
X(Y y) : member(y)
{}
int operator()(int)
{
//...
}
};
How should I modify/wrap class X so that LEGACY_CODE can access the functionality within X::operator()(int) ?

Your question makes no sense. Whose operator do you want to call?
X a, b, c;
LEGACY_CODE(???); // what -- a(), b(), or c()?
So, in short, you cannot. The member function X::operator() is not a property of the class alone, but rather it is tied to an object instance of type X.
Search this site for "member function" and "callback" to get an idea of the spectrum of possible approaches for related problems.
The crudest, and quite possibly not-safe-for-use, workaround to providing a free function would go like this:
X * current_X; // ugh, a global
int dispatch(int n) { current_X->operator()(n); }
int main()
{
X a;
current_X = &a;
LEGACY_CODE(dispatch);
}
You can see where this is going...

A simple wrapper function looks like:
int wrapperfunction(int i) {
Functor f(params);
return f(i);
}
If you want to be able to pass the parameters to the functor itself, the simplest way is to sneak them in using (brr) a global variable:
Functor functorForWrapperfunction;
int wrapperfunction(int i) {
functorForWrapperfunction(i);
}
// ...
void clientCode() {
functorForWrapperfunction = Functor(a,b,c);
legacyCode(wrapperfunction);
}
You can wrap it with a class with a static method and a static member if you want.

Here's one compile-time solution. Depending on what you need, this might be a too limited solution for you.
template<typename Func, int Param>
int wrapper(int i)
{
static Func f(Param);
return f(i);
}

A thread-safe version under the restriction that the legacy code is not called with different parameters in a thread.
IMHO, one cannot get rid of global storage.
#include <boost/thread.hpp>
#include <boost/thread/tss.hpp>
class AA
{
public:
AA (int i) : i_(i) {}
void operator()(int j) const {
static boost::mutex m; // do not garble output
boost::mutex::scoped_lock lock(m);
std::cout << " got " << j << " on thread " << i_ << std::endl;
Sleep(200); }
int i_;
};
// LEGACY
void legacy_code(void (*f)(int), int i) { (*f)(i); }
// needs some global storage through
boost::thread_specific_ptr<AA> global_ptr;
void func_of_thread(int j)
{
AA *a = global_ptr.get();
a->operator()(j);
}
void worker(int i)
{
global_ptr.reset(new AA(i));
for (int j=0; j<10; j++)
legacy_code(func_of_thread,j);
}
int main()
{
boost::thread worker1(worker,1) , worker2(worker,2);
worker1.join(); worker2.join();
return 0;
}

Related

Refactoring with AceButton Library causing "Invalid use of Non-Static member function" on compile [duplicate]

The question is the following: consider this piece of code:
#include <iostream>
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d", a, b, a + b);
}
};
void function1(void (*function)(int, int))
{
function(1, 1);
}
void test(int a,int b)
{
printf("%d - %d = %d", a , b , a - b);
}
int main()
{
aClass a;
function1(&test);
function1(&aClass::aTest); // <-- How should I point to a's aClass::test function?
}
How can I use the a's aClass::test as an argument to function1? I would like to access a member of the class.
There isn't anything wrong with using function pointers. However, pointers to non-static member functions are not like normal function pointers: member functions need to be called on an object which is passed as an implicit argument to the function. The signature of your member function above is, thus
void (aClass::*)(int, int)
rather than the type you try to use
void (*)(int, int)
One approach could consist in making the member function static in which case it doesn't require any object to be called on and you can use it with the type void (*)(int, int).
If you need to access any non-static member of your class and you need to stick with function pointers, e.g., because the function is part of a C interface, your best option is to always pass a void* to your function taking function pointers and call your member through a forwarding function which obtains an object from the void* and then calls the member function.
In a proper C++ interface you might want to have a look at having your function take templated argument for function objects to use arbitrary class types. If using a templated interface is undesirable you should use something like std::function<void(int, int)>: you can create a suitably callable function object for these, e.g., using std::bind().
The type-safe approaches using a template argument for the class type or a suitable std::function<...> are preferable than using a void* interface as they remove the potential for errors due to a cast to the wrong type.
To clarify how to use a function pointer to call a member function, here is an example:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, nullptr);
foo object;
somefunction(&forwarder, &object);
}
#Pete Becker's answer is fine but you can also do it without passing the class instance as an explicit parameter to function1 in C++ 11:
#include <functional>
using namespace std::placeholders;
void function1(std::function<void(int, int)> fun)
{
fun(1, 1);
}
int main (int argc, const char * argv[])
{
...
aClass a;
auto fp = std::bind(&aClass::test, a, _1, _2);
function1(fp);
return 0;
}
A pointer to member function is different from a pointer to function. In order to use a member function through a pointer you need a pointer to it (obviously ) and an object to apply it to. So the appropriate version of function1 would be
void function1(void (aClass::*function)(int, int), aClass& a) {
(a.*function)(1, 1);
}
and to call it:
aClass a; // note: no parentheses; with parentheses it's a function declaration
function1(&aClass::test, a);
Since 2011, if you can change function1, do so, like this:
#include <functional>
#include <cstdio>
using namespace std;
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d", a, b, a + b);
}
};
template <typename Callable>
void function1(Callable f)
{
f(1, 1);
}
void test(int a,int b)
{
printf("%d - %d = %d", a , b , a - b);
}
int main()
{
aClass obj;
// Free function
function1(&test);
// Bound member function
using namespace std::placeholders;
function1(std::bind(&aClass::aTest, obj, _1, _2));
// Lambda
function1([&](int a, int b) {
obj.aTest(a, b);
});
}
(live demo)
Notice also that I fixed your broken object definition (aClass a(); declares a function).
I asked a similar question (C++ openframeworks passing void from other classes) but the answer I found was clearer so here the explanation for future records:
it’s easier to use std::function as in:
void draw(int grid, std::function<void()> element)
and then call as:
grid.draw(12, std::bind(&BarrettaClass::draw, a, std::placeholders::_1));
or even easier:
grid.draw(12, [&]{a.draw()});
where you create a lambda that calls the object capturing it by reference
Important to note that unless you can change the signature of the code taking the function, there is no (easy) way to do this. That would be trying to implement a closure in a language that does not have closures that are the same as functions (the signature for a closure in C++ is different).
There are two actual ways to achieve this:
Use some sort of singleton/global variable that you store the closure in, and then pass a helper function that calls the needed function using that closure. Here is an example:
#include <stdio.h>
template<class C, typename ReturnType, typename... Args>
class ClosureSingleton {
typedef ReturnType (C::*FuncType)(Args...);
public:
static ClosureSingleton& getInstance() {
static ClosureSingleton instance;
return instance;
}
void setClosure(C* obj, FuncType f) {
this->obj = obj;
this->function = f;
}
static ReturnType funcPtr(Args... args) {
C* obj = getInstance().obj;
auto func = getInstance().function;
return (obj->*func)(args...);
}
private:
ClosureSingleton() {}
C* obj;
FuncType function;
public:
ClosureSingleton(ClosureSingleton const&) = delete;
void operator=(ClosureSingleton const&) = delete;
};
class aClass {
public:
void aTest1(int a, int b) { printf("%d + %d = %d\n", a, b, a + b); }
int aTest2(int a, int b) { return a + b; }
};
void function1(void (*function)(int, int)) {
function(1, 1);
}
int function2(int (*function)(int, int)) {
return function(1, 1);
}
int main() {
aClass tmp;
ClosureSingleton<aClass, void, int, int>::getInstance().setClosure(
&tmp, &aClass::aTest1);
function1(&ClosureSingleton<aClass, void, int, int>::funcPtr);
ClosureSingleton<aClass, int, int, int>::getInstance().setClosure(
&tmp, &aClass::aTest2);
printf(
"function2: %d\n",
function2(&ClosureSingleton<aClass, int, int, int>::funcPtr));
return 0;
}
Of course, this has the obvious downside that the closure needs to be set before every call, as well as some thread safety issues. Not ideal, but potentially workable in specific circumstances
Use something like asmjit or dynamic compilation to dynamically compile and pass the function in to the C code. This will only work on machines that allow heap section to be marked as executable. It is also very much non-portable as you will be writing assembly code to accomplish this. However, if you get it working, you will indeed have a true closure, albeit a substantially higher cost to creating the closure compared to how most programming languages implement closures (they do not duplicate the function assembly, instead they use a context object)
Patch the lib/dll that has the function handler to change it's signature to allow a context object. Again, a very brittle and non optimal solution.
My original answer, which does not really answer the question, but people found it useful:
Not sure why this incredibly simple solution has been passed up:
#include <stdio.h>
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d\n", a, b, a + b);
}
};
template<class C>
void function1(void (C::*function)(int, int), C& c)
{
(c.*function)(1, 1);
}
void function1(void (*function)(int, int)) {
function(1, 1);
}
void test(int a,int b)
{
printf("%d - %d = %d\n", a , b , a - b);
}
int main (int argc, const char* argv[])
{
aClass a;
function1(&test);
function1<aClass>(&aClass::aTest, a);
return 0;
}
Output:
1 - 1 = 0
1 + 1 = 2
I made the member function as static and all works:
#include <iostream>
class aClass
{
public:
static void aTest(int a, int b)
{
printf("%d + %d = %d\n", a, b, a + b);
}
};
void function1(int a,int b,void function(int, int))
{
function(a, b);
}
void test(int a,int b)
{
printf("%d - %d = %d\n", a , b , a - b);
}
int main (int argc, const char* argv[])
{
aClass a;
function1(10,12,test);
function1(10,12,a.aTest); // <-- How should I point to a's aClass::test function?
getchar();return 0;
}
If you actually don't need to use the instance a
(i.e. you can make it static like #mathengineer 's answer)
you can simply pass in a non-capture lambda. (which decay to function pointer)
#include <iostream>
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d", a, b, a + b);
}
};
void function1(void (*function)(int, int))
{
function(1, 1);
}
int main()
{
//note: you don't need the `+`
function1(+[](int a,int b){return aClass{}.aTest(a,b);});
}
Wandbox
note: if aClass is costly to construct or has side effect, this may not be a good way.
You can stop banging your heads now. Here is the wrapper for the member function to support existing functions taking in plain C functions as arguments. thread_local directive is the key here.
http://cpp.sh/9jhk3
// Example program
#include <iostream>
#include <string>
using namespace std;
typedef int FooCooker_ (int);
// Existing function
extern "C" void cook_10_foo (FooCooker_ FooCooker) {
cout << "Cooking 10 Foo ..." << endl;
cout << "FooCooker:" << endl;
FooCooker (10);
}
struct Bar_ {
Bar_ (int Foo = 0) : Foo (Foo) {};
int cook (int Foo) {
cout << "This Bar got " << this->Foo << endl;
if (this->Foo >= Foo) {
this->Foo -= Foo;
cout << Foo << " cooked" << endl;
return Foo;
} else {
cout << "Can't cook " << Foo << endl;
return 0;
}
}
int Foo = 0;
};
// Each Bar_ object and a member function need to define
// their own wrapper with a global thread_local object ptr
// to be called as a plain C function.
thread_local static Bar_* Bar1Ptr = NULL;
static int cook_in_Bar1 (int Foo) {
return Bar1Ptr->cook (Foo);
}
thread_local static Bar_* Bar2Ptr = NULL;
static int cook_in_Bar2 (int Foo) {
return Bar2Ptr->cook (Foo);
}
int main () {
Bar1Ptr = new Bar_ (20);
cook_10_foo (cook_in_Bar1);
Bar2Ptr = new Bar_ (40);
cook_10_foo (cook_in_Bar2);
delete Bar1Ptr;
delete Bar2Ptr;
return 0;
}
Please comment on any issues with this approach.
Other answers fail to call existing plain C functions: http://cpp.sh/8exun

Is there a better way to provide this function to a constructor?

I have a class A which has a constructor with a function argument: i.e.
class A {
public:
A(int (*f)(int);
};
I can create this class and have it use func() with, for example,
int func(int n);
A a(func);
I would like to invoke this class a number of times, but have it use internally func(n)+m instead of func(n). I would prefer not to change class A. I could create a new class to define the function I want
class B {
int (*func)(int n);
int m;
public:
B(int (*ff)(int),int mm) : func(ff),m(mm) {}
int myfunc(int n) { return(func(n)+m);
};
However, I don't think it is possible to convert a pointer to myfunc into a pointer with the required signature for A's constructor.
The way I have chosen is similar to the above, but with myfunc() and associated variables stored in the global space:
int m;
int (*func)(int);
int myfunc(int n) { return(func(n)+m); }
void setupmyfunc(int mm,int (*ff)(int)) { m=mm; func=ff; }
Then I can can create my A object with
setupmyfunc(m,func);
A a(myfunc);
This works, but seems inelegant to me. Is there a better way?
Stateless lambdas are implicitly convertible to function pointers so you can just use that without modifying your class A and without creating another class B. That is if I understood your question correctly.
class A {
public:
A(int (*f)(int)) {};
};
int func(int n) { return n * 10; }
auto test()
{
A a{[](int n) { return func(n) + 1; }};
}
std::function can hold callable objects (functions, function objects, member function pointers (with object to bind to), etc. It uses some type-erasure such that it can have this genericity, but comes at the cost of internal overhead to actually invoke it, often equivalent to a virtual function call.
Here's an example, where A takes a std::function, which allows you to pass in lambdas.
#include <functional>
#include <iostream>
class A {
std::function<int(int)> func_;
public:
A(std::function<int(int)> func) : func_(func) {}
int call(int x) {
return func_(x);
}
};
int foo(int x) {
return x * 123; // whatever
}
int main() {
// here's your wrapper function to do func(x)+m (m==9 in this case)
A obj([](int x) { return foo(x) + 9; });
int result = obj.call(123);
std::cout << result << '\n';
}
https://godbolt.org/z/94MfGM67K
Update:
Given the rejection of both answers so far, using std::function is out because it changes class A, and the obvious use of state-full lambdas for composition and capturing customization data is also out, you will need to get more creative and possibly ugly. If you can't change A, then you can't change the signature of the function passed to a, so making the lambda take its data as another argument is also out.
Seems to me that leaves just one thing: using state that is outside the function (i.e. global data or encoded in a template non-type template parameter) as a form of pseudo-capture that an otherwise stateless function can use. I reject the global approach in general, though there's interesting aspects to it, and only present a template solution:
Now you write your free-standing functions and can compose them with a template:
#include <iostream>
using F = int(*)(int);
class A {
public:
A(F f) : f_(f) { }
int operator()(int x) { return f_(x); } // Added for demo
private:
F f_;
};
template <F FuncF, F FuncG>
int compose(int n) {
return FuncF(FuncG(n));
}
int func(int n) { return n * 1000; }
int add888(int n) { return n + 888; }
int add999(int n) { return n + 999; }
int main() {
A a1(compose<add888, func>);
A a2(compose<add999, func>);
std::cout << a1(1) << " " << a2(1) << " " << a1(1);
}
// output: 1888 1999 1888
https://godbolt.org/z/8KsqbTcTd
This works as far back as c++11, and replacing the "using" with "typedef" it work in C++98.

c++ lambda pass around auto parameter type

I have a lambda function with an auto parameter, that I'd like to push the parameter into a an STL container (e.g. std::vector)
For example:
template <typename T>
struct A
{
A(int a, T &&t): _a(a), _t(t){}
int _a;
T _t;
void work()
{
_t(this);
}
};
void test()
{
A a(3, [](auto a_ptr)
{
std::cout << a_ptr->_a << std::endl;
});
a.work();
}
This example works just fine.
However, if I wanted to save a_ptr for later use inside a vector, I have no idea what to write in the vector template parameter.
I don't think I even could use std::function instead of auto in the lambda's parameter type since I think A's type is a recursive (T is lambda that accept a of T...)
Anyway, this is how I'm thinking of solving it, but was wondering if there's a better solution for it:
struct base_a
{
virtual void work() = 0;
};
template <typename T>
struct A : public base_a
{
A(int a, T &&t): _a(a), _t(t){}
int _a;
T _t;
virtual void work() override
{
_t(this);
}
};
void test()
{
std::vector<base_a *> v;
A a(3, [&v](auto a_ptr)
{
v.push_back(a_ptr);
std::cout << a_ptr->_a << std::endl;
});
a.work();
for (auto i: v)
{
i->work();
}
}
Is there a known design pattern for solving this?
Convert lambda to std::function without params (capturing params you need).
void execute_functions(const std::vector<std::function<void()>>& functions) {
for (const auto& item : functions) {
item();
}
}
int main(int argc, char** argv) {
// declare
std::vector<std::function<void()>> functions;
// populate
for (int i = 0; i < 3; ++i) {
functions.emplace_back([i](){ // < - capture data to process here
// do something wth data when will be called
std::cout << i << "\n";
});
}
// execute somewhere
execute_functions(functions);
return 0;
}
Example here
I can create a new lambda within the lambda that captures all the parameters and then place it into a vector:
void test()
{
std::vector<std::function <void ()>> v;
A a(3, [&v](auto a_ptr)
{
v.push_back([a_ptr](){
std::cout << a_ptr->_a << std::endl;
});
});
a.work();
for (auto &i: v)
{
i();
}
}
But I think from a user's perspective (the guy who wrote the test() function), the inheritance method is easier since there maybe multiple lambdas He'd like to keep to handle different situations.
This can make the program flow unnecessarily complicated IMO.

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

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.
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
}

Properly implementing an array of class functions

I want to make an array of known size of class functions. To do so, I've tried using typedef, but it hasn't been working out so far.
Also, some functions take no arguments ex. F(), but others do ex. G(int n), and in the typedef, I don't know how to tell it to accept no arguments for some (tried void but it says it is not a type), and to accept arguments for others.
class myClass
{
// An array of void functions
typedef void(myClass::*arrayOfFunctions)();
private:
arrayOfFunctions array[3] = { &myClass::F, &myClass::G, &myClass::H };
void F() { do stuff; }
void G(int n) { do stuff involving n; }
void H() { do stuff; }
};
What I have tried:
I have successfully made an array of void functions in a main with no classes involved which I can call when wanted, so part of the problem seems to be implementing this in a class and using its class functions.
// This works:
typedef void(*arrayOfFunctions)();
void Action1()
{
// stuff 1
}
void Action2()
{
// stuff 2
}
void Action3()
{
//stuff3
}
int main()
{
arrayOfFunctions functionArray[] = { Action1, Action2, Action3 };
// Call Action1
functionArray[0]();
return 0;
)
As was mentioned in comments, it is not possible directly. You cannot store objects of different type in the same array. However, there are ways to achieve what you want. How to get there very much depends on details. Latest when you call the function you need to know how many parameters to pass.
In your example one possibility is to refactor to have only methods with no parameters:
class myClass {
using memFun = void(myClass::*)();
void set_n(int x) { n = x; }
private:
memFun array[3] = { &myClass::F, &myClass::G, &myClass::H };
void F() { do stuff; }
void G() { do stuff involving n; }
void H() { do stuff; }
int n;
};
I changed the name of the alias, because it is just the type of a function pointer not an array. using is easier to read than typedef (it follows the more common x = something style).
When you call the function G the parameter n has to come from somewhere, so instead of passing it directly you can call set_n before iterating the array and call all mehtods without parameter.
It is not clear how you want to use such an array. If you know an element index at compile time, then you could probably use a std::tuple with template argument deduction. For example:
class my_class {
public:
template<std::size_t n, class... Args>
decltype(auto) call_fn(Args&&... args) {
constexpr auto ptrs = get_fn_pointers();
return std::invoke(std::get<n>(ptrs), this, std::forward<Args>(args)...);
}
private:
static constexpr auto get_fn_pointers() {
return std::tuple(&my_class::f, &my_class::g, &my_class::h);
}
void f() {
std::cout << "f()\n";
}
void g(int n) {
std::cout << "g(" << n << ")\n";
}
int h() {
std::cout << "h() => ";
return 9102;
}
};
int main() {
my_class c;
c.call_fn<0>(); // Output: f()
c.call_fn<1>(2019); // Output: g(2019)
std::cout << c.call_fn<2>(); // Output: h() => 9102
}