callback function with no dynamic memory allocation I tried to make a callback type for embedded, I know std::function and lambda but I know that there is some dynamic memory allocation that I want to avoid, I came to this implementation:

#pragma once
namespace interfaces
{
    template &lt;class returnType, class ... parameterType&gt;
    class ICallable
   {
       public:
       virtual returnType execute(parameterType ... args) = 0;
   };
}


static callback :

#pragma once

#include "ICallable.hpp"

template &lt;class ReturnType, class ... ParameterType&gt;
class StaticCallback : public interfaces::ICallable &lt;ReturnType,ParameterType...&gt;
{
   public:
      typedef ReturnType (*CallbackFunction)(ParameterType ...);

      constexpr StaticCallback(CallbackFunction function) : m_function(function)
      {
      }

   virtual ReturnType execute(ParameterType ... args) override final
   {
       return m_function(args...);
   }


 private:
    CallbackFunction m_function;
};


and callback with an object

#pragma once
#include "volund/interfaces/system/ICallable.hpp"

 template &lt;class objectType,class returnType,class ... parameterType&gt;
 class ObjectCallback : public interfaces::ICallable&lt;returnType, parameterType ...&gt;
 {
    public:
      typedef returnType (objectType::*Callbackfunction)(parameterType ... args);
      constexpr ObjectCallback(objectType&amp; self, Callbackfunction function) : m_object(&amp;self), m_functionToCall(function)
      {
      }
      constexpr ObjectCallback(objectType *self, Callbackfunction function) : m_object(self), m_functionToCall(function)
      {
      }
      virtual returnType execute(parameterType ... params) override final
      {
          return (*m_object.*m_functionToCall)(params...);
      }

    private:
       objectType* m_object;
       Callbackfunction m_functionToCall;
  };


I'm not sure about the reason of dynamic allocation in std::function, so I'm wondering if there is no pitfall I didn't see in my solution.
If someone have any tips or advice that would be great =)

EDIT :

This is how i use it, typically from a driver that trigger an interrupt and user code register a callback to define some code to be executed on interrupt :

class driver
{
    public:
      void setCallback(ICallable* callback)
      {
         m_callback = callback;
      }

      driver&amp; get()
      {
         return s_self;
      }

     private:
       static s_self;

       Icallable* m_callback;

       static void interrupt()
       {
          s_self.m_callback-&gt;execute();
       }
  }


  class user
  {
      public:
        void task()
        {
            driver::get().setCallback(&amp;m_callFromDriver);
            while(true)
            {
               //do something
            }
        }
       private:
         ObjectCallback m_callFromDriver = ObjectCallback(this, &amp;user::onEvent);


        void onEvent()
        {
            //do something
        }
  }
lambda's don't alloc, std::function only allocates memory if the object it is wrapping is 'too large'.  The VC++ 2019 std::function impl defines 'too large' as being more than 7 * sizeof(void*) bytes in size.  Other impl may use a different limit.  This is big enough to handle many (most ?) cases w/o allocating.

You could make your own function class, based on std::function, and put static_assert's in the constructors and assignment op's to ensure none of your code that uses your function would trigger an alloc; or if it would you could increase the 'too large' size of your function class.  This would give you something as flexible as std::function, and the control over alloc that you want.

[EDIT]

If you don't want to use the VC++ version, the gcc one is at:

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/std_function.h

To start you can copy the file and put static_assert's before lines 160 and 237 to catch any cases that would require an alloc (likely also have to check dependencies in other gcc .h files).

... it looks like this version doesn't reserve much space i.e. would alloc in many cases.  You'd have to make a couple other tweaks to increase the no_copy size.