The avr runtime does not support exceptions nor dynamic memory allocation (you can provide an implementation, thoughas has been stated. you can provide an implementation though.
more on templates
The following code uses the "curiously recurring template pattern" CRTP.
It is used to create a job class, which i use for a primitive scheduling
This template builds a chain of registrable items.
template<class registered>
struct Registered {
static registered *registry;
registered *chain;
Registered() : chain(registry) {registry=static_cast<registered*>(this);}
};
The job class applies the CRTP pattern. The constructor takes the actual callback where the work is done, and how often the job is done.
class Job : public Registered<Job>
{
voidFuncPtr m_p;
uint16_t m_periodic;
uint32_t m_lastrun;
uint16_t m_initialdelay;
public:
Job(voidFuncPtr p,uint16_t periode=0,uint16_t initialdelay=0):m_p(p),m_periodic(periode),m_lastrun(0),m_initialdelay(initialdelay)
{
}
void run(uint32_t t_ms)
{
// tbd handle wraparound !!
if(t_ms >= m_lastrun + m_periodic + m_initialdelay)
{
m_p();
m_lastrun=t_ms;
m_initialdelay=0;
}
}
};
to use the job class i just create the instances for the jobs and pass lambdas or regular function pointers
Job jserial([](){mqttrouteradapter.handleSerialMQTT();},10);
Job jupdate(updatemc,1);
Job jprint(printstate,500);
initialize the beginning of the chain of jobs
template<> Job *Registered< Job >::registry = 0;
and inside main, run an infinite loop which calls the jobs.
while (1)
{
for ( auto p = Job::registry; p; p=p->chain )
p->run(millis());
}
Lambdas
allowsAllows to deduce the type automagically. This function iterates over "something" passed the second parameter. It compiles, if the passed type provides the operations/attributes used in the function.
whilevoid runRx(1const char* data, auto msg_registry)
{
for ( auto p = Job::registry;msg_registry; p; p=pp = p->chain ) {
p->run(millis>rx()data);
}
}
using a recent compiler
If you want to use a recent compiler (The Arduino IDE uses gcc4.9) you can build your own gcc avr toolchain rather easily. Then you have gcc 7.2 with c++17 support !
My conclusion is, there is no excuse using c, except you havn't yet learned c++.