Использование макросов - это достойный подход к шаблонизации определений, то есть генерация любого количества определений на основе шаблона. Вот пример - но он ужасен как ад.
#include <stdlib.h>
#define template_struct_A(T1,T2) struct A_ ## T1 ## _ ## T2 { \
T1 a; \
T2 b; \
}
#define struct_A(T1,T2) struct A_ ## T1 ## _ ## T2
struct C { const char*s; };
typedef const char* pchar;
template_struct_A(int, pchar); // explicit instantiation of struct A<int, pchar>
int main() {
struct X { struct C x; } x;
struct_A(int, pchar) o1; // struct A<int, const char*> o1
o1.a = 1;
o1.b = "hello";
struct_A(int, pchar) o2; // struct A<int, const char*> o2
o2.a = o1.a * 2;
o2.b = "world";
typedef struct_A(int, pchar)* pAInt;
typedef struct C structC;
template_struct_A(pAInt, structC) o3; // struct A<struct A<int, const char*>, struct C> o3
o3.a = &o2;
o3.b.s = "hi";
printf ("o1.a = %d, o1.b = %s, o2.a = %d, o2.b = %s, o3.b.s = %s\n", o1.a, o1.b, o2.a, o2.b, o3.b.s);
}