У меня есть простой класс, который позволяет прерыванию (или другой подпрограмме) планировать запуск функции в следующем проходе основного кода l oop. Это работает с использованием union
для описания различных возможных шаблонов аргументов.
Как и для добавления нового типа шаблона аргумента требуется
- Добавление
typedef
для шаблона . - Добавление
struct
в объединение для представления аргументов. - Добавление объявления и функции
addDooer
для обработки добавления. - Обновление
loop
оператор переключения кода для обработки нового типа шаблона.
Образ работы для каждого нового шаблона аргумента. Я просто изучаю шаблоны и мне интересно, можно ли переписать этот класс для использования шаблонов, чтобы упростить добавление дополнительных шаблонов аргументов? И если да, могут ли шаблоны быть расширены, чтобы разрешить и другое количество аргументов?
typedef void (*looper_runner1)(uint32_t arg1, uint16_t arg2);
typedef void (*looper_runner2)(uint8_t *arg1, uint16_t arg2);
struct LoopDooer
{
uint16_t type;
union {
struct
{
uint32_t arg1;
uint16_t arg2;
looper_runner1 fn;
} type1;
struct
{
uint8_t *arg1;
uint16_t arg2;
looper_runner2 fn;
} type2;
} dooer;
};
class Looper
{
public:
Looper();
bool addDooer(looper_runner1 fn, uint32_t arg1, uint16_t arg2);
bool addDooer(looper_runner2 fn, uint8_t *arg1, uint16_t arg2);
void loop();
private:
/* ... actual methods not relevant to question */
};
bool Looper::addDooer(looper_runner1 fn, uint32_t arg1, uint16_t arg2)
{
LoopDooer *p = new LoopDooer();
p->type = 1;
p->dooer.type1.fn = fn;
p->dooer.type1.arg1 = arg1;
p->dooer.type1.arg2 = arg2;
return _add(p);
}
bool Looper::addDooer(looper_runner2 fn, uint8_t *arg1, uint16_t arg2)
{
LoopDooer *p = new LoopDooer();
p->type = 2;
p->dooer.type2.fn = fn;
p->dooer.type2.arg1 = arg1;
p->dooer.type2.arg2 = arg2;
return _add(p);
}
// To be called from main loop
void Looper::loop()
{
LoopDooer *p;
/* some code removed that just gets next LoopDooer into pointer p */
// Do it
switch (p->type)
{
case 1:
p->dooer.type1.fn(p->dooer.type1.arg1, p->dooer.type1.arg2);
break;
case 2:
p->dooer.type2.fn(p->dooer.type2.arg1, p->dooer.type2.arg2);
break;
}
// Delete it
delete p;
}