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