C++ using callbacks of an arbitrary class with arbitrary parameters - c++

I want to implement a class with a function able to callback to methods from the object that called that function, without information about it.
Imagine we want to callback to some methods of the class Game from Library:
void Game::display(string a) {
cout << a << endl;
}
int Game::sum(int a, int b) {
return a + b;
}
void Game::start() {
lib = new Library();
lib->doSomething(/* somehow pass information about the functions*/);
}
And then:
void Library::doSomething(list_of_callbacks L /*or something like this*/) {
L[0]("hi"); //L[0] is Game::display
L[1](2,3); //L[1] is Game::sum
}
It needs to work not just with Game, but with any class. The methods we want to call back may need access to the object's attributes (so not necessarily static).
I'm kinda new to C++; I've been searching on the topic for hours now but in most cases the return type or the parameters of all the callback methods are the same. I've tried to get something working with templates and std::function / std::bind but unsuccessfully.
Thanks, and sorry if I didn't make myself clear enough, it's my first post around here.
EDIT:
The doSomething function is going to be generated (translated) by an external tool, which has information about the list of functions (like, the function in L[0] takes these parameters or these others, etc).
If what I'm asking can't be done in C++, isn't there any other way to achieve the same goal? Being able to get information from the caller?

Related

How to create multiple caller functions by another function

I'm trying to create a function call stack like this, but so that it goes to caller_1_100:
void callee(void) {
// prints out final call stack
}
void caller_1_3(void) { callee(); }
void caller_1_2(void) { caller_1_3(); }
void caller_1_1(void) { caller_1_2(); }
I know I could use a recursive function to do this, but for now I want to try out both ways.
So I was wondering if there was a way to create this sort of caller functions automatically in C++, as I want to make the function call stack to go down at least 100 in depth.
However, from what I searched it doesn't seem possible in C++? Should I use python or some other language to create then change to C++?
You could use a function template with a specialization for your base case. For example:
template <size_t I>
void caller_1()
{
caller_1<I + 1>();
}
template <>
void caller_1<100>()
{
callee();
}
Keep in mind that since templates are resolved at compile time any decent optimizing compiler will almost certainly optimize out the intermediate calls, so you probably won't see them in a stack trace. See this example.
As you said, you want to have at least 100 in depth, it can be 100, 200, or others. This is like having dynamic function definition. It is not a feature of a compiled language. JS or Python can achieve this more easily.
A solution with C++ can be having a class with a id property and a public function which will be called by others. Then instantiate X instances of the class where X is your depth and call the function of the instances as you want.

Trying to pass a function from a class to a variadic template function

So I have a group project that is comparing the sort times of various sorting functions. I am trying to cut down the amount of copy/pasting code by using a variadic template function. I have read everything I can find on google about them and how to pass functions as parameters. It has been literally DAYS of working on this, and I can't seem to make this work. I've been able to pass a function that is defined in my main cpp file outside of a class, but I can't make it work for the functions that belong to a class.
My group has asked me to abandon this idea (we are running out of time), but I feel like I am so close to getting it. If anyone can help out with the syntax, I would be so grateful. I also tried using the function type from the functional library, which was the only way that semi-worked. I did find this question on stack overflow and the guy had the same error I was getting about using '&', but I still can't seem to make this work.
edit
As per the comments, I tried to make the code as basic and concise as possible. :)
I spent more time than I should have trying to find the function that I had gotten to work, but I did not save a copy of it. I read that I should include code that allows others to duplicate the error, but I have not been able to re-create it. The best I can do is a hypothetical example at this point.
Lets say I have a function in a class called Sorts:
void Sorts::InsertionSort(vector<int> &v_small, int length)
{
//does the thing that sorts the stuff
cout << "display the sorted stuff" << endl
}
and a vector in a class called Data:
class Data{
public
vector<int> dataSmall;
};
both of these are in a separate header file. For simplicity, lets call it "header." :)
run_timer(InsertionSort, vector_to_sort, size_of_vector);
I also have a function, in my cpp file, that (is attempting) to take a function parameter, a vector parameter, and a size parameter.
template <class Ret, class... Args> class function<Ret(Args...)>
run_timer3(function<void(Args...)> sort_func(int), vector<int>& array, int size...)
{
//start the timer
//call function to time, sort_func sometimes has 3 parameters though
sort_func(array, size);
//stop the timer
//calculate and write to file
}
I know I should be able to figure this out with generic examples but I'll just be honest it does not compute. All I need is to know how to pass a function that exists in a class. Although now that I lost the function that was working, maybe I need some help making the function definition as well. :(
This was probably the most helpful page I had found on variadic templates.
Sorry if this is to similar to the one I linked before, but I really can't understand what it is I'm doing wrong. I really don't want to have to have the same block of code with different variables 162 times. If anyone can offer guidance I will send you cyber feet-kisses. Thanks!
Since your question contains way more code then I feel like sifting through, I'll just give you an example on how to pass a function to a template.
#include <iostream>
template <typename F>
void foo(F f) {
f();
}
struct bar {
void print() {
std::cout << "bar\n";
}
void baz() {
foo([&]() { print(); });
}
};
void print() {
std::cout << "free\n";
}
int main () {
foo(print);
bar b;
b.baz();
foo([&]() { b.print(); });
}
A free function can simply be passed in. If you want to pass a member-function you can wrap it in a lambda.

Passing function pointer with scope resolution operator arduino

I'm a newbie to arduino and programming.
I've included a library inside my own library in arduino, but first library contains a function which has a pointer function as a parameter. It is an interrupt service routine(ISR) but I need to call a function in my cpp file when interrupt is occurred. So I need to pass the pointer of that function to the first library code. It works well when I use it in .ino file, I can pass it like,
attachInterrupt(functionISR_name);
but when I use it in .cpp file, I get errors. my function is like,
void velocity::functionISR_name(){
//some code
}
but how can I pass the pointer of this function to the first library function? I tried this way but got errors,
attachInterrupt(velocity::functionISR_name);
You cannot pass a method to a function which expects a function, unless you define it static.
write it static :
static void velocity::functionISR_name()
and
attachInterrupt(&velocity::functionISR_name);
Unfortunately the static method is not bound to a specific instance any more. You should use it only together with a singleton. On Arduino you should write the class like shown below in the code snipped:
class velocity
{
static velocity *pThisSingelton;
public:
velocity()
{
pThisSingelton=this;
}
static void functionISR_name()
{
pThisSingelton->CallWhatEverMethodYouNeeded();
// Do whatever needed.
}
// … Your methods
};
velocity *velocity::pThisSingelton;
velocity YourOneAndOnlyInstanceOfThisClass;
void setup()
{
attachInterrupt(&velocity::functionISR_name);
// …other stuff…
}
This looks ugly, but in my opinion it is totally okay with Arduino as the opportunities are very limited on such a system.
Thinking again over it, I would personal go for the approach Sorin mentioned in his answer above. That would be more like that:
class velocity
{
public:
velocity()
{
}
static void functionISR_name()
{
// Do whatever needed.
}
// … Your methods
};
velocity YourOneAndOnlyInstanceOfThisClass;
void functionISR_name_delegation()
{
YourOneAndOnlyInstanceOfThisClass.functionISR_name();
}
void setup()
{
attachInterrupt(functionISR_name_delegation);
// …other stuff…
}
It would also save you some bytes for the pointer you need in the first example.
As a site note: For the future, please post the exact code (for e.g. attachInterrupt needs more parameter) and copy&paste the error messages. Usually error are exact at a place you do not suspect. This question was an exception. Normally I and other would ask for better specification.
You pass a pointer to the function but the function is a class member. Likely the call will be invalid because the this pointer will be garbage(may compile fine but will throw strange errors at runtime).
You need to define a plain vanilla function, outside of any class, and use that.
If you don't have a very complex project you can get away with having a global pointer to the class instance you should use and just delegate the call in your new function.
If you want to do thing the right way you need some mechanism to get the instance pointer I talked about above. Usually this involves either a singleton or some factory pattern.
Example:
class Foo {
void method() {
x = 5;
}
int x;
}
Having a callback on method will crash because you have an invalid pointer for this so x=5 will write 5 somewhere randomly in memory.
What you need is somehting like:
static Foo* foo_instance; // Initialized somewhere else.
void method_delegator() {
foo_instance->method();
}
Now you can pass method_delegator to the function. It will work because you now also pass foo_instance for this pointer.

Should I and how do I create progress reporting in computation demanding algorithms in c++

I am implementing some Deep Learning Neural Networks and existing code from Matlab normaly just prints out to the console such users have an idea of progress.
When I am doing my design for C++ and have put core parts of the algorithms into separate functions that I do not want to print stuff out to the console, are there ways or design principles for leaving a option to the users who use the algorithm to get some kind of progress indication?
Could one let a optional parameter be a function pointer that people could hook into, or how would I do this?
void my_heavy_algorithm(int * data, int n,...);
If you are exposing your algorithm as a collection of functions then the way to go would be to have one of the parameters be a function pointer with a signature like this:
void (*reportProgress)(void*, int)
But if you are designing your algorithm in C++ you should probably take advantage of encapsulation and create a class (or set of classes) for your algorithm. In this case you wouldn't want to add the function pointer as a parameter to the individual functions.
Rather you might make the function pointer a member of your class. And have accessor methods to get/set it. Or even better, provide an abstract class for reporting progress.
class ProgressReporter
{
public:
virtual ~ProgressReporter() = 0;
virtual void notifyProgressChanged(void* source, int progressValue) = 0;
}
class Algo
{
private:
ProgressReporter* _userProvidedReporter = NULL;
public:
void set_ProgressReporter(ProgressReporter*); // set accessor
ProgressReporter* get_ProgressReporter(); // get accessor
void my_heavy_algorithm(int*, int, ...); // your algo. implementation fn.
}
void Algo::set_ProgressReporter(ProgressReporter* reporter){
_userProvidedReporter = reporter;
}
ProgressReporter* Algo::get_ProgressReporter(){
return _userProvidedReporter;
}
void Algo::my_heavy_algorithm(int * data, int n,...){
// do stuff
if(_userProvidedReporter != NULL)
_userProvidedReporter->notifyProgressChanged((void*)this, currentProgress);
// do more stuff
if(_userProvidedReporter != NULL)
_userProvidedReporter->notifyProgressChanged((void*)this, currentProgress);
// so on and so forth..
}
Of course the above is a pretty simplistic example. If you expect your algorithms to support concurrency you should synchronize access to the internal user reporter and you might consider creating a base class for your algorithm and provide concrete derived implementations..
STL style functors may help you. This would also allow yor algorithm be used withoud any progress indicator.
For example, let's say you'd like to give a percent progress indicator.
// disclaimer - I didn't compile this code
class NoProgressFeedback; // see below
void my_heavy_algorithm(int * data, int n, ProgressFeedback giveFeedback = NoProgressFeedback() {
int percentProgress = 0;
giveFeedback(percentProgress);
/* start calculations, do stuff */
percentProgress++;
giveFeedback(percentProgress);
/* continue over and repeat percentProgress updates and giveFeedback calls */
}
/* NoProgressFeedback will do no progress feedback */
class NoProgressFeedback {
public:
operator()(int percent) {}
}
If user code wants feedback, then it should pass your my_heavy_algorithm function a different progress indicator, that sould look like this:
class GetProgressFeedback {
public:
void operator()(int percent) { std::cout << "percent advance: " << percent; }
}
Take a look at Dependancy Injection.
You can pass an object that implements an IProgress interface. A NullProgress object could just have the stubs but does no real work for objects you aren't interested in monitoring.
The usual way is to run your computationally heavy work in seperate thread and use that to update a section of memory via a lock. The UI thread then reads periodically from this memory location and updates the screen accordingly.
To report proper progress, you need three things:
An estimate of the total work to be done.
An estimate of how much work has been done so far.
A source of time.
You also need some way for your "heavy math" function to "report in". One way to do that is to have some sort of function that you call in the "start of function", "progress so far" and "end of function". The start of function also sets "total amount of work to do". Progress so far reports "how much is done now", and "end of function" says "I'm complete".
In a C++ class environment, this could be done as:
class Progress
{
Progress() { };
virtual void Start(int todo) = 0;
virtual void Done(int doneSoFar) = 0;
virtual void Finish();
};
This provides an interface that other classes can be derived from.
Of course, you still need to find a useful pace to put your "Done()" - if you put it too deep inside some tight loop, it will impact performance, but you need to do it often enough that it shows some useful progress too.

How do you clone() in linux inside a class and namespace?

I'm taking an intro to operating systems course and we're to use the clone() call in linux to create threads and then do some stuff with them. I seem to be having trouble just using clone() at all.
I've structured my code into a single class (called Homework) which is in the namespace for the class (Course). This may be the problem as this is the first time I've really used the namespace keyword. I'm trying to use the things I rarely do to become more experienced with it so if I have a dumb mistake, so be it.
I found some articles on the web but they didn't help much. I've read the man page but I guess I'm not experienced enough to understand what the problem is. One day! Thanks for any assistance :)
I want to have the method to catch the clones inside the class:
// -- Header -- //
namespace _Course_ {
class _Homework_ {
...
int threadCatch(void *);
...
};
}
// -- Source -- //
namespace _Course_ {
void _Homework_::threadTest(void) {
...
// From web article
void **childStack;
childStack = ( void **) malloc(KILOBYTE);
clone(threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL);
...
}
int _Homework_::threadCatch(void * ){
cout << getpid() << " cloned." << endl;
exit(0);
}
}
Is what I currently have. I've tried different ways (taking the catcher out of the class, then namespace). It's compiled twice but when I try to recompiled after a make clean it tells me the function (threadCreate) is declared in multiple locations. Because of these weird errors I'm sure I'm doing something wrong and instead of hack at it I'll take some opinions. What should I do, or what should I read next? Thanks!
Define your catch function as a static class function.
static int threadCatch(void *);
Also (and you probably don't need this, but just in case, I'll say it here) you might also need to use the scope resolution operators to send it to clone(). I don't think so, since you're using it inside of the Homework class already. but I say it just in case, it might help you.
clone(Homework::threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL);
The clone(2) system call expects a pointer to a function with C linkage. Since you're using C++ I'd recommend moving your threadCatch() function into the global namespace and declare it as an extern "C" function. You could also declare the method in your class as static but I feel that making it a free function with C linkage more closely matches how the function is to be passed as a parameter.
If you need to make calls to C++ objects inside your threadCatch() function that exist outside of it's scope you can pass pointers to those objects as the arg parameter to the clone() call. Your threadCatch() function would then cast the arg to the appropriate type so that you can access your C++ object(s) accordingly.