Question: I am building a c++ class library for embedded projects.
One concept I have is a class named Task.
Task has 2 members: 
An integer id and a callback function pointer 

The callbacks are created by the user and given to the constructor of the class.

I want to give the following options to the user:

* The user may use functions of type `void(*)(void)`
* The user may use function of type `void (*)(unsigned int)`. That parameter should be the id of the task, when the callback is called.
* The user may use a combination of the above function types for different tasks

The tasks also have an execute() method that calls the callback function. This method should also provide the task id as an argument, if needed

One solution would be to add a boolean member in Task called 'has\_arguments' and overload the constructor to set it with regard to the type of function pointer it was given in the code.
I could also use a union for the callback member or use a void pointer and cast it to whatever suitable during execution.
The execution of the task would involve checking the 'has\_arguments' member, casting the pointer to the appropriate type and calling the callback in the right way.

But is there any way to avoid this extra member and check?

I tried to always cast the function pointers to void(\*)(unsigned int) and always provide the argument when I called them. And it worked.

So is it that bad to call a functions that takes no arguments, with an argument?
It worked for me, but I suppose that it is a really bad practice.
Any other ideas on what I could implement instead?

I don't want to dictate to the users to make functions with variable arguments lists. I want to leave them the freedom to use simple task agnostic functions, 
or make more intelligent functions that are aware of their task ID

Answer: 
If you cannot use `std::function` due to limitation of embedded platform use `union` and a tag, then properly set `type` by overloaded setter or ctor and in call use a `switch` on `type`:

```
struct Task {
    enum CallbackType {
        cbVoid,
        cbId
   };
   using VoidCb = void(*)(void);
   using IdCb = void(*)(unsigned);

   int          id = 0;
   CallbackType type;
   union {
       VoidCb vcb;
       IdCb  idcb;
   } function;

   Task( VoidCb cb ) : type( cbVoid ), function( cb ) {}
   Task( IdCb cb ) : type( cbId ), function( cb ) {}

   void call() {
       switch( type ) {
           case cbVoid : function.vcb(); return;
           case cbId : function.idcb( id ); return;
       }
   }
};

```
You can create something under the covers that looks like the same interface. That is, auto-create helper wrapper functions that can throw away the task id if the callback doesn't want it.

```
class Task {

    template <void (*CB)(void)> struct task_void {
        static void cb (int) { CB(); }
        operator Task () const { return Task(*this); }
    };

    template <void (*CB)(int)> struct task_int {
        static void cb (int id) { CB(id); }
        operator Task () const { return Task(*this); }
    };

    static volatile int next_id_;

    int id_;
    void (*cb_)(int);

    template <typename CB> Task (CB) : id_(next_id_++), cb_(CB::cb) {}

public:
    template <void (*CB)(void)> static Task make () { return task_void<CB>(); }
    template <void (*CB)(int)> static Task make () { return task_int<CB>(); }
    void execute () { cb_(id_); }
};

```

The private constructor is accessible to the helper templates for initialization. The helper templates can choose to hide the parameter or not.

So now, you can create a task with either kind of callback.

```
void cb_void () {
    std::cout << __func__ << std::endl;
}

void cb_int (int id) {
    std::cout << __func__ << ':' << id << std::endl;
}

//...
    Task t1 = Task::make<cb_void>();
    Task t2 = Task::make<cb_int>();
    t1.execute();
    t2.execute();

```