How to pass function object to a function as callback c++ [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
as little follow up to this: C++ lambda function without C++0x?
I have created the lambda function as a function object without c0x
the question now is:
how to pass it as a callback/function pointer to another function?
My first try was like this, but it didn't work:
Lambda Obj( C, D);
command ( Obj.operator()(typeA A, typeB B));
I marked the other question to early i guess, so noone looked at the edit.

If you cannot find std::function in std::tr1::function or via std::function or via a compiler upgrade...
Write your own std::function-like type eraser, or use boost, or use 'the fastest possible delegates' (that should google to a complete implememtation), or pass both a this pointer and a method pointer as template-type-deduced arguments to a function, or pass a template-type-deduced copy of the function object to the function.
Note that the last two options require the function's body to be exposed (such as in a header file).
Or convert the function object into a void* style C callback.
I would go with C++11, and failing that boost, and failing that fast delegates, failing that write a type eraser myself, failing that stick body in header and template+pass a copy (unless function is simple, in which case do this first), and failing that pvoid C style.

Using Boost.Bind:
void command(boost::function<void()> func)
{
func();
}
Lambda Obj(C, D);
command(boost::bind<void>(Obj, A, B));
(or maybe you wanted to have):
void command(boost::function<retType(typeA, typeB)> func)
{
retType ret = func(A, B);
}
Lambda Obj(C, D);
command(boost::bind<retType>(Obj, _1, _2)); // placeholders
Using templates (the STL's way):
template <typename F>
void command(F func)
{
func(A, B);
}
Lambda Obj(C, D);
command(Obj);
Live demo link.

Related

Why can't I access the object using the arrow operator [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Suppose I have
struct B
{
template<typename T>
void doSomething(T& bar);
};
class A
{
//... (ctor etc.)
template<typename T>
void foo(const std::string& name, T& bar)
{
for(auto& data : myData)
{
if(data.first == name)
*(data.second)->doSomething(bar); //ERROR
}
}
private:
std::vector<std::pair<std::string, B**>> myData;
};
I thought this would work because we are iterating over 'myData' by reference, i.e. no copies, and then we do *(data.second) to access a pointer to B, which we then use the '> operator to access its 'oSomething Method.
Instead, I am just getting the error:
member reference base type 'B' is not a structure or union*
which makes no sense to me since B* is a pointer to a struct, and using the '->' operator on that would dereference the pointer revealing the actual class.
GodBolt Reproduction: https://godbolt.org/z/c45oMT
And the error mentioned in the question is because *(data.second)->doSomething(bar) is really the same as *(data.second->doSomething(bar)).
That is you try to call data.second->doSomething(bar) which is not possible because data.second is a pointer to a pointer to an object.
Then you attempt to dereference whatever doSomething returns, which also isn't possible since it doesn't return anything.
What you probably want is something like
(*data.second)->doSomething(bar);
This will first dereference data.second removing one indirection, resulting in a pointer to B (i.e. *data.second results in a B*). Then call the function on that object.

How to make a callback in C++: use a class member function as a parameter [duplicate]

This question already has answers here:
Callback functions in C++
(11 answers)
Closed 2 years ago.
I started using C++ recently and at one point I needed to set up a callback, i.e. call a function of another class and pass to it as a parameter the name of one of my own functions so that it calls it back. At first I tried this:
void myOtherFunction(void (*oneOfMyFunctions)(void)) {
oneOfMyFunctions();
}
Unfortunately this code doesn't support class member functions because it is (correct me if I am wrong) ...C code.
This can work.
void myOtherFunction(void (*oneOfMyFunctions)(void)) {
oneOfMyFunctions();
}
However, your problem may be due to trying to pass member functions into this function. If member_function is a member function of class A, the expression &member_function inside class A has a type of void (A::*)(void), not void (*)(void) like you want (that is, it wants an A pointer in addition to its normal parameters). You can use std::bind():
std::bind(&member_function, this)
to create a function object which can be called with an empty parameter list. However, then you would need to change your member function signature to something like this:
template <typename FuncType>
void myOtherFunction(FuncType oneOfMyFunctions) {
oneOfMyFunctions();
}
or, like Th0rgal may have said,
void myOtherFunction(std::function<void()> oneOfMyFunctions) {
oneOfMyFunctions();
}
Here is a working way to do that:
void myOtherFunction(std::function<void()> oneOfMyFunctions) {
oneOfMyFunctions();
}
And inside my class:
myOtherFunction([&] {
oneOfMyFunctions();
});
Some explanations:
In std::function<void()>, void is what is returned by the function and () contains the types of its parameters (mine is empty because it doesn't have any).
In the 2nd code I am using a lambda to keep the context, as a bind would do (but lambdas replace them).

Initialization without recursion [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to do a bit of refactoring and I am curious about how would you approach this problem.
Basically I'm trying to create an initialization function for each class. There are classes that inherit from some others, and i would like to use parent initialization function if possible. How would you address this?
I would like to use these structs with memcpy and maybe using also them with the keywords align and __attribute__((packed)); and they must be usable with extern "C". I would exclude then constructors and destructors.
An example to explain:
struct A
{
int a;
};
void initialize(A& a)
{
a = 0;
}
struct B : A
{
int b;
};
void initialize(B& b)
{
initialize(b); // here I want void initialize(A& a), not recursion
b = 0;
};
Maybe I have to do some kind of cast? Ideally I'm looking a solution that does not create overhead.
Use a static_cast.
In your code, the initialize(b) call will recurse infinitely, because b is better matched as B& than as A& (the argument of the function you want to call), thus the overload resolution picks the same function and recurs.
You specified that you want to initialise the A part of the b object. Why not tell that to the compiler? Tell it that you want to call initialise in it as though it was an A, like so:
initialize(static_cast<A&>(b));
As for your concern that you mentioned in the comment - no copies are being made here. If I used static_cast<A>, however, a temporary object would be created, but that's not the case. I am not casting b to an object of a type A. I am casting it to a reference of a type A, which will result in creation of temporary reference. Since A& matches with A& better than with B&, the first function will be chosen, thus avoiding the recursion.

How to pass function without using & [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I often write code where I have the following scenario.
I have a (pure) function f and another function g which is templated so that it takes a callable object, say with similar type as f, as an argument.
Now often f is not super trivial but a couple of lines long and since it
is it is stateless I define f as a normal function. But then when passing f I have to write &f and I really dislike the syntax.
Another way would be to write a global lambda or a functor, that would fix my "& issue". But syntactically I prefer normal functions...
So is there a way to define g such that I can pass f as a normal function but avoid the &?
You do not have to explicitly take the address of a function when passing it. As an example, the following code compiles and works:
template <typename F>
void foo(F f) { f(); }
void bar() { }
int main()
{
foo(bar);
}
live example on wandbox.org

Mixed values of arguments, when I call pointer member function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have called a pointer of member function from another class. This function has 2 arguments.
It is working... But in this member function, in the debugger, I see that values of arguments were swapped (mixed). I see the correct values but not in correct variables(arguments). May be it is BUG...
Qt Creator c++
void SmartCTL::OnReadBufferA(int shm_id, int length); //declaration
hookedIDs[HOOKIDPOINTERS::READBUFFERA] = (void *)&SmartCTL::OnReadBufferA; // Save pointer of function
memcpy(hookedIDs[smartCTL.shellID],smartCTL.hookedIDs,8*sizeof(void *));// copy pointers
void (*pf)(int,int )= (void(*)( int,int ))hookedIDs[i][HOOKIDPOINTERS::READBUFFERA];// set pointer
pf(shells[i]->readBuff.shm_id,shells[i]->readBuff.length); // call hear
In result I get value hells[i]->readBuff.shm_id in length and value shells[i]->readBuff.length in shm_id
This isn't a bug. What you have is undefined be behavior. A member function is not the same as a regular function. There is a this in the member function and the way it gets that is through an implicit function parameter of the class type. So
void SmartCTL::OnReadBufferA(int shm_id, int length)
is really something like
void SmartCTL::OnReadBufferA(SmartCTL& this_ref, int shm_id, int length)
And this is why you can't cast a pointer to a member function to a pointer to a regular function.
If you need to have both member functions and regular functions in your "array" then you are going to need a std::function. It uses type erasure to allow you to to store different types of function objects that have the same interface. For example you could have something like
std::vector<std::function<void(int, int)>> functions;
functions.push_back(some_regular_function);
functions.push_back([](int shm_id, int length){ SmartCTL s; return s(shm_id, length); });
Another option is to make the member function a static function. A static function does not have a instance of the class bound to it so you can treat it as a regular function.