Я пытаюсь добиться перегрузки метода в C, предпочтительно используя макросы, чтобы заголовок / библиотека могли обрабатывать определения и объявления вместо того, чтобы помещать это на пользователя. Сейчас я прочитал ответ об использовании _Generic
, но проблема в том, что мои функции имеют struct
типы. Так что нет никакого способа оценить их тип, используя __typeof__
из _Generic
. Интересно, есть ли вообще какой-либо способ.
Вот так выглядит мой заголовочный файл (это все, что нас должно интересовать) -
#pragma once
// Macros for generic like use of the data structure
// Macros for the stack type itself
/*
* Define stack with corresponding type
* Converts Stack(int) to intstack_t
*/
#define Stack(type) type stack_t
// Macros for functions
/*
* Define createStack function
* Converts createStack(int, 5) to create_intstack(5)
*/
#define createStack(type, capacity) create_ ##type ##stack(capacity)
/*
* Define destroyStack function
* Converts destroyStack(someIntStack) to destroy_intstack(someIntStack)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define destroyStack(stack) _Generic(stack, intstack_t*: destroy_intstack, charstack_t*: destroy_charstack)(stack)
/*
* Define push function
* Converts push(someIntStack, data) to intstack_push(someIntStack, data)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define push(stack, data) _Generic(stack, intstack_t*: intstack_push, charstack_t*: charstack_push)(stack, data)
// Stack structure definition(s)
// int stack definition
typedef struct IntegerStack {
int top;
unsigned capacity;
int* arr;
}intstack_t;
// char stack definition
typedef struct CharacterStack {
int top;
unsigned capacity;
char* arr;
}charstack_t;
//Stack functions
// int stack functions
intstack_t* create_intstack(int);
void destroy_intstack(intstack_t*);
void intstack_push(intstack_t*, int);
// char stack functions
charstack_t* create_charstack(int);
void destroy_charstack(charstack_t*);
void charstack_push(charstack_t*, char);
Большинство объявлений функций ( и косвенно, их соответствующие макросы были удалены, поскольку все они по существу функционируют одинаково. Меня интересует только макрос функции push
, как указано. Другие макросы действительно показывают, какой тип использования я собираюсь использовать. Очевидно, что макрос, используемый в push
с использованием _Generic
, не будет работать, поскольку intstack_t
или charstack_t
не являются примитивными типами.
Цель состоит в том, чтобы пользователь мог использовать push(stack, data)
, где стек может быть переменной типа intstack_t*
или charstack_t*
, а оператор push(stack, data)
будет преобразован в intstack_push(stack, data)
или charstack_push(stack, data)
соответственно.