C99结构内的函数重载

时间:2019-07-07 17:21:07

标签: c function struct c99

通常,在C99中,可以使用 VA_ARGS 和诸如此类的宏技巧来实现函数重载(参数数量,而不是类型重载):

#define THIRD_PARAMETER(_1,_2,_3,...) _3
#define NOTHING

例如:

void pr1(int x);
void pr2(int x, int y);
#define pr(...) THIRD_PARAMETER(__VA_ARGS__, pr2, pr1, NOTHING)(__VA_ARGS__)

(我添加了NOTHING宏,以便当我调用...打印pr(100)时,C99不会抱怨传递给100的零参数,我希望我的程序是与C99完全兼容)

但是问题是:pr不是函数,因此不能将它分配给struct内部的函数指针:

 // this is a dynamic array
 struct array {
     // ...
     void (*insert)(struct array * a, ...);
     // ...
 };

假设我有3个版本的insert:single_insert,multiple_insert,range_insert,它们分别具有3、4、5个参数。如何在C99结构中实现函数重载(参数数量)?有可能吗?

2 个答案:

答案 0 :(得分:2)

  

假设我有3个版本的insert:single_insert,multiple_insert,   range_insert,分别具有3、4、5个参数。我怎么能够   在C99中实现函数重载(参数数量)   结构?有可能吗?

您可以声明一个不提供原型的函数指针,因此将与具有不同数字甚至不同类型参数的函数兼容:

void (*insert)();

但是指向的任何函数都是通过这样的指针调用的函数-您将不会基于参数列表选择不同的函数。此外,参数将接受默认参数提升,并且提升后的参数必须在类型和数量上与实际函数参数一致。

如果指针声明确实提供了原型,并且您通过它调用了指向函数,则该函数必须具有兼容的签名,因为在语言规范中定义了“兼容”。特别是可变参数和非可变函数声明彼此不兼容,因此,用可变参数原型声明指针的想法是不一致的。

因此,它实际上与结构无关。相反,问题在于函数指针。您可以应用您描述的宏技巧来在多个函数指针中进行选择,或者可以编写可变参数包装函数来执行这种选择,但是不能将这种选择编码到指针本身中。

答案 1 :(得分:0)

您可以为.insert函数指针赋予任意类型(如果您使用void (*)()之类的东西,则采用非短参数或可变参数的void重现函数将转换为该指针类型隐式,但这不是必须的),然后有一个INSERT(&myarray, ...)宏来对参数进行计数,根据计数将.insert转换为适当的类型,然后调用它。