2014-01-06 3 views
3

У меня есть такой код:Сокращение дублирования кода и замена #define с шаблонами

#define defaultOnTimer(N, X) \ 
if (Timers.N) Timers.N --; \ 
if (!Timers.N) S.X = D.X; \ 

defaultOnTimer(t1, sig1); 
defaultOnTimer(t2, sig2); 
defaultOnTimer(t3, sig3); 
defaultOnTimer(t4, sig4); 

Хотя это работает, мне интересно, если можно было бы использовать ++ шаблон C за ту же работу. «defaultOnTimer» может быть расширен в будущем для дополнительной работы, поэтому я не хочу просто дублировать его столько раз, сколько необходимо, а затем искать и изменять каждый из них.

Или это просто слишком сложная работа, и я должен просто придерживаться #define?

Обратите внимание, что S.X может быть любого типа.

+1

Нет шаблоны не могут сделать именно это. Они могут сделать что-то подобное, если вы хотите немного изменить интерфейс (и S - тот же тип, что и D). –

ответ

0

Это выглядит ужасно, но он работает как-то:

template<typename A, size_t N, typename B, size_t X> 
void onTimer() 
{ 
    A& n = *(A*)(&Timers + N); 
    if (n) 
    { 
     --n; 
    } 
    if (!n) 
    { 
     *(B*)(&S + X) = *(B*)(&D + X); 
    } 
} 

вот пример:

struct Timer 
{ 
    int t1, t2, t3, t4; 
}; 
struct Sig 
{ 
    char sig1, sig2, sig3, sig4; 
}; 

Sig S, D; 
Timer Timers; 

void a() 
{  
    onTimer<int, offsetof(Timer, t1), char, offsetof(Sig, sig1)>(); 
} 

Но D, S и Timers должны быть глобальными переменными. Вы можете избежать этого, передавая их в качестве аргументов функции:

template<typename A, size_t N, typename B, size_t X> 
void onTimer(Timer* timer, Sig* sigS, Sig* sigD) 
{ 
    A& n = *(A*)(timer + N); 
    if (n) 
    { 
     --n; 
    } 
    if (!n) 
    { 
     *(B*)(sigS + X) = *(B*)(sigD + X); 
    } 
} 

void a() 
{  
    Sig S, D; 
    Timer Timers; 
    onTimer<int, offsetof(Timer, t1), char, offsetof(Sig, sig1)>(&Timers, &S, &D); 
} 

Я думаю, что это ответ на ваш вопрос, но это все еще капризное решение

Смежные вопросы