1

I am trying to store a function pointer to be callbacked later like so:

Task->Sync->SetPeriodicTask( &TaskAssigner::ReadAndRelay );

TaskAssigner class declares void ReadAndRelay() and it holds a SyncManager* Sync object.

(It may be odd, but the child object Sync needs to call back to its parent class' function at certain intervals).

I attempt it like this:

void SyncManager::SetPeriodicTask(std::function<void()> func) {
    CB_func_periodic = func;
    //CB_func_periodic = std::bind(&func, this, std::placeholders::_1);
}

Member variable declaration (SyncManager.h):

private:
    using func = std::function<void()>;
    func CB_func_periodic;

I am not sure what is the correct syntax here, as I get so many errors. Tried searching the errors, but I couldn't find an answer that suits my case, and I don't want the parameter of SetPeriodicTask(..) to be too complicated for other users to write. How should I approach this?

  • 1
    The code inside SetPeriodicTask should be `CB_func_periodic = func;`. The argument to SetPeriodicTask should be different – M.M May 31 '18 at 03:35
  • 1
    It would improve the question to post a [MCVE](http://stackoverflow.com/help/mcve) as there are several unknowns based on what you have posted – M.M May 31 '18 at 03:36
  • @M.M I tried what you suggested before, but with the same argument. In what way should it be different.. ? – Mads Midtlyng May 31 '18 at 03:40
  • What is `TaskAssigner::ReadAndRelay`??? I don't see it defined in your code. Anyway, most likely your `TaskAssigner::ReadAndRelay` is simply not `void ()`. That's why you get errors. If `TaskAssigner` declares a non-static `void ReadAndRelay()`, then it is `void TaskAssigner::()`, which is very different from `void ()`. – AnT stands with Russia May 31 '18 at 03:45
  • @AnT it doesn't make sense to try and bind `this` of whatever `Sync` is , to pointer-to-member of `TaskAssigner` – M.M May 31 '18 at 03:47
  • @AnT ReadAndRelay is a simple void (). – Mads Midtlyng May 31 '18 at 03:48
  • @MadsMidtlyng your question suggests `ReadAndRelay` is actually a class member function – M.M May 31 '18 at 03:49
  • @Mads Midtlyng: No, it isn't. A non-static member function is *never* a simple `void ()`. Only a freestanding function (or a static member) can be `void ()`. Non-static member functions are beasts of completely different nature - they always have an implicit `this` parameter. – AnT stands with Russia May 31 '18 at 03:49
  • @M.M Sorry, yes, I meant to say it is a member class with a void return type, and void of parameters. – Mads Midtlyng May 31 '18 at 05:39

1 Answers1

2

Here is some sample code based on the details you have posted so far:

#include <functional>

using func = std::function<void()>;

struct S
{
    func CB_func_periodic;
    void SetPeriodicTask( func f ) { CB_func_periodic = f; }
};

struct R
{
    void ReadAndRelay() {}
    S s;
};

int main()
{
    R r;
    r.s.SetPeriodicTask( [&] { r.ReadAndRelay(); } );
}

The argument to SetPeriodicTask should be a Callable, because that function calls it. The address of member function is not callable.

The code should be structured so that the periodic task cannot be invoked after r is destroyed.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • This helped me get the syntax correct and the code working again. Thanks for the lesson! – Mads Midtlyng May 31 '18 at 07:45
  • If I may add a follow up question; How can I check if void SetPeriodicTask( func f )'s f is NULL? Or set it to NULL specifically? – Mads Midtlyng May 31 '18 at 07:50
  • 1
    @MadsMidtlyng see `https://stackoverflow.com/questions/21806632/how-to-properly-check-if-stdfunction-is-empty-in-c11`. Basically you can do `if (f)` to check, and `f = nullptr;` – M.M May 31 '18 at 08:00