После прочтения нескольких примеров по стеку и следуя некоторым ответам на мои предыдущие вопросы ( 1 ), я в конечном итоге пришел к «стратегии» для этого.
Я пришел к этому:
1) Есть раздел объявления в файле .h
. Здесь я определю структуру данных и интерфейс доступа. Eg.:
/**
* LIST DECLARATION. (DOUBLE LINKED LIST)
*/
#define NM_TEMPLATE_DECLARE_LIST(type) \
typedef struct nm_list_elem_##type##_s { \
type data; \
struct nm_list_elem_##type##_s *next; \
struct nm_list_elem_##type##_s *prev; \
} nm_list_elem_##type ; \
typedef struct nm_list_##type##_s { \
unsigned int size; \
nm_list_elem_##type *head; \
nm_list_elem_##type *tail; \
int (*cmp)(const type e1, const type e2); \
} nm_list_##type ; \
\
nm_list_##type *nm_list_new_##type##_(int (*cmp)(const type e1, \
const type e2)); \
\
(...other functions ...)
2) Обернуть функции в интерфейсе внутри MACROS:
/**
* LIST INTERFACE
*/
#define nm_list(type) \
nm_list_##type
#define nm_list_elem(type) \
nm_list_elem_##type
#define nm_list_new(type,cmp) \
nm_list_new_##type##_(cmp)
#define nm_list_delete(type, list, dst) \
nm_list_delete_##type##_(list, dst)
#define nm_list_ins_next(type,list, elem, data) \
nm_list_ins_next_##type##_(list, elem, data)
(...others...)
3) Реализация функций:
/**
* LIST FUNCTION DEFINITIONS
*/
#define NM_TEMPLATE_DEFINE_LIST(type) \
nm_list_##type *nm_list_new_##type##_(int (*cmp)(const type e1, \
const type e2)) \
{\
nm_list_##type *list = NULL; \
list = nm_alloc(sizeof(*list)); \
list->size = 0; \
list->head = NULL; \
list->tail = NULL; \
list->cmp = cmp; \
}\
void nm_list_delete_##type##_(nm_list_##type *list, \
void (*destructor)(nm_list_elem_##type elem)) \
{ \
type data; \
while(nm_list_size(list)){ \
data = nm_list_rem_##type(list, tail); \
if(destructor){ \
destructor(data); \
} \
} \
nm_free(list); \
} \
(...others...)
Чтобы использовать эти конструкции, мне нужно создать два файла (назовем их templates.c
и templates.h
).
В templates.h
мне нужно будет NM_TEMPLATE_DECLARE_LIST(int)
, NM_TEMPLATE_DECLARE_LIST(double)
, а в templates.c
мне понадобится NM_TEMPLATE_DEFINE_LIST(int)
, NM_TEMPLATE_DEFINE_LIST(double)
, чтобы иметь код за списком целых, двойных и и так далее, сгенерировано.
Следуя этой стратегии, мне придется хранить все мои «шаблонные» объявления в двух файлах, и в то же время мне нужно будет включать templates.h
всякий раз, когда мне нужны структуры данных. Это очень «централизованное» решение.
Знаете ли вы другую стратегию для "подражания" (в какой-то момент) шаблонам в C ++? Знаете ли вы, как улучшить эту стратегию, чтобы сделать ее более децентрализованной, чтобы мне не понадобились два файла: templates.c
и templates.h
?