This question already has answers here:
Using generic std::function objects with member functions in one class
(6 answers)
Closed 5 years ago.
What is the approach to have a vector to schedule method calls of a class. I would like to have a vector of methods, something like this:
class Model {
using task_t = std::function<void()>;
std::vector<std::vector<task_t>> _frameTasks;
void add_function() { _frameTasks[3].push_back(&(this->function()); }
void function() {std::cout << "hi"; }
void step() {
for (auto task : _frameTasks[3]) task();
}
}
But the compiler complains that:
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.
How could I solve this issue or what is the right approach?
&(this->function()) is applying & to the result of the call to the function() member function. The default operator& requires an lvalue, however, the expression this->function() is not an lvalue.
Writing &Model::function won't work either because it is a pointer to a member function (as opposed to a pointer to a function). Its type is void (Model::*)(), i.e.: a pointer to a Model's (non-static) member function that takes no parameters and returns nothing.
You need some way to specify the Model object on which the function() member function will be called.
Since C++11 you can achieve that by simply using a lambda expression:
void add_function() {
_frameTasks[3].push_back(
[this](){ add_function(); }
);
}
Related
This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
how to pass a non static-member function as a callback?
(8 answers)
Pass Member Function as Parameter to other Member Function (C++ 11 <function>) [duplicate]
(2 answers)
Closed 4 months ago.
I need to change the prototype of a function pointer of a class. So, I was hoping inheriting it and doing the following would work, but it doesn't ("invalid use of non-static member function 'void B::myIntCallback(unsigned int)"):
class A {
public:
typedef void (*intCallback_t)(unsigned int myInt);
A(intCallback_t intCallback) {}
};
class B : A {
public:
typedef void (*charCallback_t)(unsigned char myChar);
B(charCallback_t charCallback) : A(this->myIntCallback) {
charCallback_ = charCallback;
}
private:
charCallback_t charCallback_;
void myIntCallback(unsigned int myInt) {
charCallback_((unsigned char)myInt);
}
};
Does anybody know how I can solve this? I can't change class A.
You are trying to pass a member function (B::myIntCallback) to a function pointer argument. Since the member function needs an object to be called on, his would require some kind of capturing, e.g. a lambda capturing this or an std::bind expression. Unfortunately, neither is possible with a plain function pointer, see also Passing capturing lambda as function pointer.
If possible, you may want to consider changing the class A to accept either a std::function or a template argument as the type of the callback. See also Should I use std::function or a function pointer in C++?.
This question already has answers here:
C++ Call Pointer To Member Function
(4 answers)
Calling C++ member functions via a function pointer
(10 answers)
Closed 9 months ago.
Consider this class:
class Downloader {
private:
bool video_or_audio;
// other variables [...]
// [...]
void downloadVideo(std::string videoURL);
void downloadAudio(std::string audioURL);
public:
void download();
}
Now, download() is defined this way:
void Downloader::download(){
std::ifstream url_list;
void (*download_func)(std::string) = video_or_audio == 0 ? downloadVideo : downloadAudio; // Compiler says here: "Reference to non static member function must be called".
if(video_or_audio == 0){
url_list.open("video_list.txt");
}
else{
url_list.open("audio_list.txt");
}
std::string url;
while(std::getline(url_list, url)){
download_func(url); // Calling the function pointed by the pointer defined in line 2 of the function download().
}
}
My compiler (clang) says: "Reference to non static member function must be called" in the second line of function download() definition. Why is this happening and how can I solve this problem?
A solution appears to be defining downloadVideo() and downloadAudio() functions to be static in the class declaration. However, if I do so, I cannot access private variables members of class Downloader, that's not desirable, as I need these variables.
Thank you!
Once calling a member function by pointer, you need to provide two things:
Member function itself
Address of particular instance of given class at which the member function to be called (because the function can access class members thus you have to advise which of the instances is the right one)
void (Downloader::*download_func)(std::string) = video_or_audio == 0 ? &Downloader::downloadVideo : &Downloader::downloadAudio; // Correct the signatures.
...
while(std::getline(url_list, url)){
(this->*download_func)(url);
}
So, here we changed download_func from "just function pointer" to a member function pointer. Then, later in the loop body, we call this member function on this instance (however you can pass an instance as a param if necessary).
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).
This question already has answers here:
C++ class member function pointer to function pointer
(4 answers)
Closed 2 years ago.
I have two classes, say A and B; I want to store a function pointer of B in a wrapper function<void()> in A.
The ultimate goal is to be able to call OnRender() at multiple places in A, but OnRender() is defined at runtime (say I want to choose one B among many).
How could this be done ?
class A
{
public:
function<void()> OnRender{}; // I want to use this
void (B::*OnRender)(){}; // I want to avoid this
}
class B
{
public:
auto SomeJob() -> void;
}
I could store a function pointer like this:
someA.OnRender = &B::SomeJob;
// OK if I use void (B::*OnRender)(){};
But I also want to avoid referencing the class B in A.
ANSWER:
I can store a lambda like this:
someIntanceOfA.OnRender = [&](){ someB->SomeJob(); };
// OK if I use function<void()> OnRender{};
Or with safety measures:
someA.OnRender = [&](){ if(somB != nullptr) someB->SomeJob(); };
Function pointer to a non static class member method cannot be typecasted to normal non-class--method function pointer. If done, it's an undefined behaviour and most certainly results in crash.
The reason is that, an object of that class is required to invoke it's method.
Your conventional pointer to member syntax is better.
Refer:
Casting between void * and a pointer to member function
casting member function pointer
C++ class member function pointer to function pointer
This question already has answers here:
Using generic std::function objects with member functions in one class
(6 answers)
Closed 4 years ago.
I have a similar situation:
class A {
void callingFunction() {
calledFunction(passedFunction);
}
void calledFunction(std::function<void(int)> foo) {
}
void passedFunction(int arguments) {
}
};
The compiler error is
error: invalid use of non-static member function
How do I achieve this without making the passedFunction static?
Doing this:
calledFunction(std::bind(&A::passedFunction, this);
Creates this error:
error:static assertion failed: Wrong number of arguments foor pointer-to-member
Does it mean I have to provide all the arguments in the callingFunctionwhen passing the passedFunction? This is not possible as the arguments for the passedFunction are specified in the calledFunction
You can write a lambda capturing this, on which passedFunction could be called.
calledFunction([this](int v) { this->passedFunction(v); });