【发布时间】:2020-04-14 14:27:34
【问题描述】:
我正在尝试在 C 中实现方法重载,最好使用宏,以便标头/库可以处理定义和声明,而不是将其交给用户。现在我已经阅读了这个answer 关于使用_Generic 但是问题是我的函数有struct 类型。所以没有办法使用_Generic 的__typeof__ 来评估他们的类型。我想知道有没有什么办法。
这就是我的头文件的样子(这是我们应该关心的全部)-
#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) 或@987654337 @分别。
【问题讨论】:
-
这可能是可能的,但它可能会使您的代码难以阅读和维护。
-
不使用类型,而是使用
void *并存储指向不透明类型的指针。 -
我真的不想使用 void 指针,因为它可能会使代码类型不安全并引发严重的漏洞。我对难以阅读/维护的代码很好,但我不希望它不安全,除非明确需要
-
您在
_Generic调用中省略了控制表达式。我假设您的意思是(stack)。但是为什么类型不是原始类型很重要? -
@rici 我的错,我没有注意到我缺少参数。但它不适用于“intstack_t”或“charstack_t”类型,因为_Generic 不允许这些类型,它只允许像
int、long等基本类型
标签: c struct macros c-preprocessor