How to execute a function from another function? - c++

I have this code:
#ifndef FUNCSTARTER_H
#define FUNCSTARTER_H
#endif // FUNCSTARTER_H
#include <QObject>
class FunctionStarter : public QObject
{
Q_OBJECT
public:
FunctionStarter() {}
virtual ~FunctionStarter() {}
public slots:
void FuncStart(start) {
Start the function
}
};
In the FuncStart function, you would put your function in as a parameter and then it would execute the parameter (aka the function). How would I do this?

either you pass a function pointer, or you define a functor class. A functor class is a class that overloads operator(). This way, the class instance becomes callable as a function.
#include <iostream>
using namespace std;
class Functor {
public:
void operator()(void) {
cout << "functor called" << endl;
}
};
class Executor {
public:
void execute(Functor functor) {
functor();
};
};
int main() {
Functor f;
Executor e;
e.execute(f);
}

You'd pass the function pointer as parameter. This is called a callback.
typedef void(*FunPtr)(); //provide a friendly name for the type
class FunctionStarter : public QObject
{
public:
void FuncStart(FunPtr) { //takes a function pointer as parameter
FunPtr(); //invoke the function
}
};
void foo();
int main()
{
FunctionStarter fs;
fs.FuncStart(&foo); //pass the pointer to the function as parameter
//in C++, the & is optional, put here for clarity
}

Related

Callable being required to be static in C++ class template

I would like to have the following class setup in a program:
A class that implements a buffer. This buffer, when full, would spawn a thread that makes a callback to handle what to do with the full buffer.
A base class template that includes a buffer object. Implements the callback function, which makes a call to a virtual function defined in a derived class.
A derived class that inherits from base class and implements what to do with the data.
First, the minimal reproducible example:
#include <vector>
#include <iostream>
#include <thread>
template <typename T>
class CallbackBuffer
{
public:
std::vector<T> buffer;
void (*callback)(std::vector<T>);
std::thread writerThread;
CallbackBuffer(int bufferSize = 10)
{
buffer.resize(bufferSize);
}
void setCallback(void (*cb)(std::vector<T>))
{
callback = cb;
}
void writeCall()
{
writerThread = std::thread(callback, buffer);
}
};
template <typename T>
class Base
{
public:
CallbackBuffer<T> buffer;
Base()
{
buffer.setCallback(bufferHandler);
}
void bufferHandler(std::vector<T> v)
{
for(auto &i : v)
{
write(i);
}
}
virtual void write(T i) = 0;
};
class Derived : public Base<int>
{
public:
Derived()
{
}
void write(int i)
{
std::cout << i << std::endl;
}
};
int main()
{
Derived d;
return 0;
}
I'm getting the following compiler error:
error: invalid use of non-static member function ‘void Base<T>::bufferHandler(std::vector<T>) [with T = int]’
So the compiler needs bufferHandler to be static, but if I did that, then I would not have access to the object's members. Is there a way to sort this, or just a horrible idea?
You are passing the class member function so you need to have in your CallbackBuffer class something like:
void (Base<T>::*callback)(std::vector<T>);
// ...
void setCallback(void (Base<T>::*cb)(std::vector<T>)) {
callback = cb;
}
and in Base class:
Base() {
buffer.setCallback(&Base<T>::bufferHandler);
}
Demo
Member function pointers have different type than regular functions, that's why your code does not work. What you may want is using std::function instead of raw pointers:
#include <functional>
//...
std::function<void(std::vector<T>)> callback;
// ...
void setCallback(const std::function<void(std::vector<T>)>& cb) {
callback = cb;
}
and pass it like that:
Base() {
buffer.setCallback([this](auto& vec){ this->bufferHandler(vec); });
}
IMHO this is much more readable and flexible than passing around member pointers

Calling a class member function from a thread using pthread_create

Below is the code
#include <iostream>
#include <pthread.h>
using namespace std;
class Base
{
private:
public:
void *threadCall1( void * value)
{
cout<<"inside threadCall1"<<endl;
}
protected:
};
class Derived
{
private:
public:
void *threadCall2 ();
protected:
};
void *Derived::threadCall2()
{
cout<<"inside threadCall2"<<endl;
}
int main ()
{
int k = 2;
pthread_t t1;
cout<<"inside main"<<endl;
Base *b = new Base();
pthread_create(&t1,NULL,&b->threadCall1,(void *)k);
return 0;
}
Error
main.cc: In function int main()': main.cc:46: error: ISO C++ forbids
taking the address of a bound member function to form a pointer to
member function. Say&Base::threadCall1' main.cc:46: error: cannot
convert void*(Base::*)(void*)' tovoid*()(void)' for argument 3'
toint pthread_create(pthread_t*, const pthread_attr_t*,
void*()(void), void*)'
I agree C++ forbids this call but is there any way I can call a class member function using posix thread
You can do this via a function that dispatches the work accordingly:
#include <iostream>
#include <pthread.h>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}
int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}
Live example
pthread_create accepts a pointer to arbitrary data for the thread function. Pass the address of your object, and use a forwarding function such as the thread_adapter defined above. Inside the adapter function, you can static_cast the argument back to a Base* inside your thread function and invoke the member function as desired.
However, you may want to look into the std::thread library, which supports such operations in a more natural way:
#include <iostream>
#include <thread>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}
Live example
There's no such thing as &b->threadCall1. Fortunately, pthread allows you to pass a void ptr to the class (the one you're filling with k). Pass b as this void ptr to a global (or static member) function that simply calls b->threadCall1(); then move k to an attribute of Base instead of an argument of Base::threadCall1().
You cannot use pointer to member function as thread routine. Consider to use thead context structure to pass need information to the thead routine:
struct thread_context {
Base* object;
void (Base::*func)(void*);
};
void *thread_routine(void *arg) {
thread_context* context = static_cast<thread_context*>(arg);
context->object->(*context->func)(nullptr);
...
}
...
thread_context context = {
b1,
&Base::threadCall1
};
pthread_create(&t1,NULL,&thead_routine, &context);

Calling a function that takes std::function as an argument

I have the following code that implements a callback. I would like the callback to take some arguments but can only get it to compile with no arguments.
#include <iostream>
#include <string>
#include <functional>
template<typename TDeserialisable>
class Images;
class Analyze;
class X
{
void operator()(...) {}
};
/** Interface for serialising/deserialising types defined by TDeserialisable */
template<typename TDeserialisable>
class IDeserialisable
{
public:
virtual void deserialise(std::function<void()> callback) = 0;
virtual void deserialise(std::function<void(IDeserialisable<TDeserialisable>&)> callback) = 0;
};
class Analyze
{
public:
void operator()()
{
// deserialise
}
void operator()(Images<Analyze>& images)
{
// deserialise
}
};
template<typename TDeserialisable>
class Images : public IDeserialisable<TDeserialisable>
{
private:
virtual void deserialise(std::function<void()> callback)
{
callback();
}
virtual void deserialise(std::function<void(IDeserialisable<TDeserialisable>&)> callback)
{
callback(*this);
}
};
int main()
{
Analyze a;
Images<Analyze> images;
// calls the first overload
static_cast<IDeserialisable<Analyze>&>(images).deserialise(a);
// how do I call the second overload of deserialise?
return 0;
}
How do I call the second overload of deserialise?
You need to specify the input parameter type as a function parameter to the std::function template type. Something like:
std::function<void(Analyze&, Images<Analyze>&)> mf_p = Analyze::operator();

Pass method as callback from one class to other class

I have 2 class, I would like to pass a method from one to other by callback!
See that I also wish to hold the address of this method using void (*callBack)();
I'm used to do this in C, but I dont know how to do this in c++;
#include <iostream>
using namespace std;
class A
{
private:
void (*callBack)(); //to hold the address of the method
public:
A();
void setCallBack(void(*cB)());
void useCallBack();
};
A::A()
{
}
void A::setCallBack(void(*cB)())
{
callBack = cB;
}
void A::useCallBack()
{
callBack();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(someMethod);
Aguy->useCallBack()
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
The problem is that:
void (*callBack)();
This is not a pointer to a method. This is a pointer to a function.
To have a pointer to a method you need to specify the class the method is in.
void (B::*callBack)();
Then when you call it you need to call it via an object.
void A::useCallBack(B* b)
{
(b->*callBack)();
}
But this is probably not what you want.
What you really want is a wrapper that encapsulates all this.
I would take a look at std::function. This will allow you to wrap a method call and an object into a single object that you can then call.
std::function<void()> callback;
Just replace all your occurrences of void(*cB)() with std::function<void()> then you can bind an instance of the object to the method at the call point.
Aguy->setCallBack(std::bind(&B::someMethod, this));
This also allows you to seemly pass any normal function or functor as a callback.
void print()
{ std:cout << "It worked\n";
}
...
Aguy->setCallBack(&print);
struct Printer
{
void operator()() const
{
std::cout << "It worked with obejct\n";
}
}
...
Aguy->setCallBack(Printer());
If you need to pass member function pointers see the modified code. it uses modern c++ constructs.
#include <iostream>
#include <functional>
using namespace std;
class A
{
private:
typedef std::function<void()> some_void_function_type;
some_void_function_type f_;
public:
A();
void setCallBack(some_void_function_type f);
void useCallBack();
};
A::A()
{
}
void A::setCallBack(some_void_function_type f)
{
f_ = f;
}
void A::useCallBack()
{
f_();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(std::bind(&B::someMethod, this));
Aguy->useCallBack();
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}
See c++ - <unresolved overloaded function type> for details.
To quote the answer:
In C++, member functions have an implicit parameter which points to
the object (the this pointer inside the member function). Normal C
functions can be thought of as having a different calling convention
from member functions, so the types of their pointers
(pointer-to-member-function vs pointer-to-function) are different and
incompatible. C++ introduces a new type of pointer, called a
pointer-to-member, which can be invoked only by providing an object.
Put static on someMethod:
class B
{
private:
A * Aguy;
public:
B();
static void someMethod();
void otherMethod();
};
void B::otherMethod() {
Aguy->setCallBack(B::someMethod);
Aguy->useCallBack(); // adding missing semicolon
}

Calling template pointer to member function

Im working on a GUI and i want to be able to pass function pointers to my buttons, however, these could be called from different kinds of classes, which is why i made it use templates.
I do believe it stores the function pointer correctly but i cannot call it correctly.
class MainMenuScene: public Scene
{
public:
void add_button(){
void (MainMenuScene::*func)();
func = &MainMenuScene::test;
Button b(func);
b.click();
}
void test();
private:
GUI<MainMenuScene> gui;
};
template<class T>
class Button: public GUI_object{
public:
Button(void (T::*func)());
void click(){
func_();
private:
void (T::*func_)();
};
This is the error i get:
Button.h|23|error: must use '.*' or '->*' to call pointer-to-member function
in '((Button<MainMenuScene>*)this)->Button<MainMenuScene>::func_ (...)',
e.g. '(... ->* ((Button<MainMenuScene>*)this)->Button<MainMenuScene>::func_) (...)'|
The function that you store a pointer to is not a static function so you need an object instance to call it.
Something like this maybe:
class MainMenuScene: public Scene
{
public:
void add_button(){
void (MainMenuScene::*func)();
func = &MainMenuScene::test;
Button<MainMenuScene> b(this, func);
b.click();
}
void test();
private:
GUI<MainMenuScene> gui;
};
template<class T>
class Button: public GUI_object{
public:
Button(T* obj, void (T::*func)());
void click(){
(obj_->*func_)(); }
private:
void (T::*func_)();
T* obj_;
};
A member function pointer must be used on a specific object. For example, in your case you would need a MainMenuScene object on which to call your function pointer.
Example:
class MainMenuScene
{
public:
void test() {
std::cout << "Hello!" << std::endl;
}
};
int main()
{
void (MainMenuScene::*myPointerToMember)() = &MainMenuScene::test;
MainMenuScene myObj{};
MainMenuScene* myObjP = &myObj;
(myObj.*myPointerToMember)(); //Parentheses around (myObj.*myPointerToMember) are important
(myObjP->*myPointerToMember)();
}