2

我想知道为什么我以前从未见过以下在 C 中实现模板的方法。我的想法是使预处理器用于模板工作。

容器.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);

主.c

#define TEMPLATE_TYPE int
#include "container.h"

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

那么,到底是怎么回事?

  1. 这只是被认为是“坏风格”
  2. 太明显了,没有人会写一篇关于它的文章
  3. 有很多文章,只是google man!

当您不打算回答 #3 时,我将不胜感激有关此技术的评论。

4

2 回答 2

5

你可以用预处理器做一些不可思议的事情(好的和坏的)。它是否被认为是糟糕的风格是一种判断,它在很大程度上取决于产生的代码的质量、可读性和可维护性。复杂的预处理器宏很难编写、调试和维护。但是,最好的 C 代码是您编写的代码,而宏非常适合自动生成主题的变体。

以下是一些使用预处理器 (ab) 的好例子:

SimpleScalar 代码使用上面您建议的模式,其中#include 前面有一个#define,它为标题提供了一些方向。

如果您正在考虑认真使用预处理器,您应该查看Boost 预处理器库。(不要被 Boost 的 C++ 根源所推迟,预处理器宏与 C 一起工作得很好。)

于 2012-06-22T22:18:38.387 回答
3

代替

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

你可能想做

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

为了能够做到

#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;
}
于 2012-06-22T22:28:30.613 回答