简体   繁体   English

使用预处理器在C中进行模板化

[英]Templating in C using the Preprocessor

I'm wondering why I have never seen the following way to implement templates in C before. 我想知道为什么我以前从未见过以下方法在C中实现模板。 My idea was to make the Preprocessor to the templating-work. 我的想法是让预处理器成为模板工作。

container.h : container.h

#ifndef TEMPLATE_TYPE
    #error "missing decalaration TEMPLATE_TYPE"
#endif

#define _CONCAT(a, b) a##b
#define _EVALUATOR(a, b) _CONCAT(a, b)
#define MAKE_NAME(a, b) _EVALUATOR(a, b)

typedef struct {
    TEMPLATE_TYPE   data;
} MAKE_NAME(Container_, TEMPLATE_TYPE);

main.c : main.c

#define TEMPLATE_TYPE int
#include "container.h"

int main() {
    Container_int c;
    c.data = 99923;
}

So, what's the case? 那么,情况如何呢?

  1. This is just considered "bad style" 这只是被认为是“坏风格”
  2. It's so obvious that nobody would write an article about it 很明显,没有人会写一篇关于它的文章
  3. There are a lot of articles, just google man! 有很多文章,只是google man!

I would appreciate comments about this technique when you are not planning to answer with #3. 如果您不打算用#3回答,我将非常感谢您对此技术的评论。

You can do incredible things (good and evil) with the preprocessor. 你可以使用预处理器做出令人难以置信的事情(善与恶)。 Whether it's considered bad style or not is a judgement call, and it largely depends on the quality, readability, and maintainability of the code that results. 它是否被认为是不好的风格是一种判断调用,它在很大程度上取决于所产生的代码的质量,可读性和可维护性。 Complicated preprocessor macros are a pain to write, debug, and maintain. 复杂的预处理器宏很难编写,调试和维护。 However, the best C code is the code you don't write, and macros are great for automatically generating variations on a theme. 但是,最好的C代码是您编写的代码,宏非常适合自动生成主题的变体。

Here are some good examples of preprocessor (ab)use: 以下是预处理器(ab)使用的一些很好的例子:

The SimpleScalar code uses a pattern like your suggestion, above, where the #include is preceded by a #define that gives the header some direction. SimpleScalar代码使用了一个类似于你的建议的模式,其中#include前面是#define,它给出了标题的某个方向。

If you're considering serious use of the preprocessor, you should look at the Boost preprocessor library . 如果您正在考虑认真使用预处理器,则应该查看Boost预处理器库 (Don't be put off by Boost's C++ roots, the preprocessor macros work fine with C.) (不要被Boost的C ++根推迟,预处理器宏可以与C一起工作。)

Instead of 代替

typedef struct {
    TEMPLATE_TYPE   data;
} MAKE_NAME(Container_, TEMPLATE_TYPE)

you might want to do 你可能想做

#define MAKE_CONTAINER(type) typedef struct MAKE_NAME(Container_, type) { type data; } MAKE_NAME(Container_, type)

in order to be able to do 为了能够做到

#include "container.h"
MAKE_CONTAINER(int);
MAKE_CONTAINER(double);

int main() {
    Container_int c; // one way to go
    struct Container_double d; // my preferred way: don't typedef when not needed; let the structs be obvious.

    c.data = 99923;
    d.data = 3.5;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM