哪种方式更适合在C中创建与类型无关的结构?

时间:2011-08-15 18:59:59

标签: c types generic-programming

我正在尝试编写一些通用结构。基本上,我需要的是C ++模板,但由于我是用C语言编写的,因此不考虑模板。目前我正在考虑实现我想要的两种方式。

方法1:使用预处理器。像这样:

#define DEFINE_PAIR(T) typedef struct Pair_##T{ \
                           T x; \
                           T y; \
                        } Pair_##T

DEFINE_PAIR(int);

int main(){
   Pair_int p;
   return 0;
}

它的明显缺点是你必须在使用该类型之前调用宏。可能还有更多的缺点,我希望你能指出。

方法2:只使用void-pointers,如下所示:

typedef struct Pair{
   void* x;
   void* y;
} Pair;

显然,这种方法不是类型安全的(我可以很容易地将一对字符串传递给期望一对双精度的函数),而且使用这种方法进行重新分配的代码会变得更加混乱。

我想听听你对此的看法。这两种方法中哪一种更好/更差?为什么?有没有其他方法可以用来在C中编写通用结构?

感谢。

3 个答案:

答案 0 :(得分:4)

如果您只打算使用原始数据类型,那么您原来的基于宏的解决方案似乎非常有用。但是,当您开始将指针对存储在下面具有复杂结构的不透明数据类型时,通过在函数之间传递指针来使用它们,例如:

complex_structure_type *object = complex_structure_type_init();
complex_structure_type_set_title(object, "Whatever");
complex_structure_type_free(object);

然后你必须

typedef complex_structure_type *complex_structure_type_ptr; 

以便

DEFINE_PAIR(complex_structure_type_ptr);

所以你可以

Pair_complex_structure_type_ptr p;

然后

p.x = object;

但这只是一点点工作,所以如果你觉得它适合你,那就去吧。您甚至可以将自己的预处理器放在一起,通过代码,拉出任何类似Pair_whatever的东西,然后为C预处理器添加DEFINE_PAIR(无论如何)。无论如何,这绝对是你在这里提出的一个巧妙的想法。

就个人而言,我只会使用void指针而忘记强类型安全性。 C只是没有与其他语言相同的类型安全机制,你忘记某些东西的机会越多,你就会意外地创造出越多的错误。

祝你好运!

答案 1 :(得分:2)

注意到c ++中的模板提供了用于编写代码的语言,您可以简单地考虑使用比c预处理器更强大的工具来生成代码。

现在确实为你的构建添加了另一个步骤,并使你的构建取决于另一个收费(除非你想在c ...中编写你自己的生成器),但它可以提供你想要的灵活性和类型安全性。

答案 2 :(得分:1)

这几乎是一样的,但它更灵活一点:

#define PAIR_T(TYPE) \
    struct { \
        TYPE x; \
        TYPE y; \
    }


typedef PAIR_T(int) int_pair;
typedef PAIR_T(const char *) string_pair;

int main(void)
{
    int_pair p = {1, 1};
    string_pair sp = {"a", "b"};
}