2

I have a function such as:

typedef void(*timercallback)(void);
void timer1_attachInterrupt(timercallback userFunc);

I wish to call a member method rather than a C style function, so I have tried the following lambda:

timer1_attachInterrupt([this](void) -> void { _member_method(); });

However I get the compiler error:

No suitable conversion function from "lambda [] void () -> void" to "timercallback" exists

As far as I can see, the lambda has void arguments like the typedef, and returns void like the tyepdef. What am I missing?

uhsl_m
  • 322
  • 3
  • 11

2 Answers2

6

What am I missing?

The lambda creates a closure object since it needs to capture state. Therefore you can't just pass it where a regular function pointer is expected.

Since your API doesn't make any provisions for passing state to the callback, you will need to use something unpleasant like global variables.

If you can modify timer1_attachInterrupt1, then I suggest you allow it to accept any (type-erased) functor. std::function is just the utility to accomplish that:

using timercallback = void(void);
void timer1_attachInterrupt(std::function<timercallback> userFunc);

1It's quite clear the OP can't after the edit. But I leave the suggestion for anyone who may be able to modify their functions.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
-1

Ok, I wanted to comment on the answer, but because of rep. points I can't directly. Mine is not answer, but comment on the above std::function<> suggestion.

You /op must really watch out: the std::function may new()/ malloc inside it's implementation. If that was me, that would be the last thing i want - any heap allocations when dealing with ISRs. (And worse, un-controlled allocations/de-allocations due to create/destroy).

It's not worth it in what you trying todo.

v01d
  • 189
  • 1
  • 12