对于这样的模板,有一个相当简单的宏转换;主要的语法问题是你不能返回结果数组,写入它的变量必须是另一个参数。
#define map(func_, input_, output_, type_, n_) do { \
output_ = xmalloc(sizeof(type_) * (n_)); \
size_t i_; \
for (i_ = 0; i_ < (n_); i_++) \
output_[i_] = func_(input_[i_]); \
} while (0)
如果您注意编译器警告,这并不像看起来那样类型不安全。但是,如果使用此宏的任何实际参数不是简单的标识符,则不是特别安全。最重要的是,如果任何实际参数有副作用,就会发生灾难性的事情。
这可以解决,无法返回结果数组也可以解决,但前提是您愿意使用 GNU 扩展...
#define gnumap(func_, input_, type_, n_) ({ \
__typeof(func_) func__ = (func_); \
__typeof(input_) input__ = (input_), \
output__ = xmalloc(sizeof(type_) * n__); \
__typeof(n_) n__ = (n_), \
i__; \
for (i__ = 0; i__ < n__; i__++) \
output__[i__] = func__(input__[i__]); \
/* return */ output__; \
})
我会在现实生活中做这些吗?可能不是,但有时它确实是最糟糕的可用选项。把它想象成比用汇编语言重写那个关键的内部循环还差一步。
(xmalloc
如果您不熟悉它,它是用户编写的包装器的常规名称,malloc
它要么成功要么使整个程序崩溃。我在这里使用它来回避如何应对malloc
失败的问题。)