C语言 C 中的伪泛型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16522341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pseudo-generics in C
提问by fb55
I need to implement some methods that do stuff with different kinds of number arrays. Usually, I'd use generics for that job, but as C doesn't provide them, I'm now trying to emulate them using macros.
我需要实现一些方法来处理不同类型的数字数组。通常,我会使用泛型来完成这项工作,但由于 C 不提供它们,我现在尝试使用宏来模拟它们。
Here's an example of what I'm trying to do:
这是我正在尝试做的一个例子:
#ifndef TYPE
#define TYPE int
#endif
TYPE get_minimum_##TYPE (TYPE * nums, int len){
TYPE min = nums[0];
for (int i = 1; i < len; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
return min;
}
However, this won't compile. The clang error message:
但是,这不会编译。叮当错误信息:
error: expected ';' after top level declarator
错误:预期';' 在顶级声明符之后
Is there any way to do this in C? Or do I need implement this for every type by hand?
有没有办法在C中做到这一点?还是我需要手动为每种类型实现这个?
回答by Paul R
You can do something like this in a header file:
你可以在头文件中做这样的事情:
//
// generic.h
//
#define TOKENPASTE(x, y) x ## y
#define GET_MINIMUM(T) TOKENPASTE(get_minimum_, T)
TYPE GET_MINIMUM (TYPE) (TYPE * nums, size_t len){
TYPE min = nums[0];
for (size_t i = 1; i < len; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
return min;
}
and then #includeit in a source file for each required type, e.g.:
然后#include它在每个所需类型的源文件中,例如:
//
// generic.c
//
#define TYPE int
#include "generic.h"
#undef TYPE
#define TYPE float
#include "generic.h"
#undef TYPE
You can test this by running it through the preprocessor:
您可以通过预处理器运行它来测试它:
$ gcc -E generic.c
int get_minimum_int (int * nums, size_t len){
int min = nums[0];
for (size_t i = 1; i < len; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
return min;
}
float get_minimum_float (float * nums, size_t len){
float min = nums[0];
for (size_t i = 1; i < len; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
return min;
}
回答by Jehan
Actually, the best you can do is to define a macro that will generate the function for the given type.
实际上,您能做的最好的事情就是定义一个宏来为给定类型生成函数。
#define define_get_minimum(T) \
T get_minimum_##T(T* nums, int len){ \
T min = nums[0]; \
for (int i = 1; i < len; i++) { \
if (nums[i] < min) { \
min = nums[i]; \
} \
} \
return min; \
}
Then, you can call that macro to define the specializations you need (with C++ template, a similar thing is done automagically by the compiler).
然后,您可以调用该宏来定义您需要的专业化(使用 C++ 模板,类似的事情由编译器自动完成)。
define_get_minimum(int)
define_get_minimum(double)
define_get_minimum(float)
Another thing that a C++ compiler does automagically is deduce the overloaded function you need. You can't have that in C, so you will have to tell you are using the it specialization. You can simulate a template-like syntax for your function with the following macro (the C++ <>are just replaced by ()):
C++ 编译器自动执行的另一件事是推导您需要的重载函数。你不能在 C 中拥有它,所以你必须告诉你正在使用它专业化。您可以使用以下宏为您的函数模拟类似模板的语法(C++<>只是由 替换()):
#define get_minimum(T) get_minimum_##T
Then, you should be able to call it the following way:
然后,您应该可以通过以下方式调用它:
int main()
{
// Define arr as char* array...
// Do stuff...
int res = get_minimum(int)(arr, 3);
}
I did not test this code, but it should work.
我没有测试这段代码,但它应该可以工作。
回答by truth_seeker
You can also use function pointers (Array of function pointers), other than a switch statement, and pass the argument of the switch as the index to the array.
您还可以使用函数指针(函数指针数组),而不是 switch 语句,并将 switch 的参数作为索引传递给数组。

