通常,在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结构中实现函数重载(参数数量)?有可能吗?
答案 0 :(得分:2)
假设我有3个版本的insert:single_insert,multiple_insert, range_insert,分别具有3、4、5个参数。我怎么能够 在C99中实现函数重载(参数数量) 结构?有可能吗?
您可以声明一个不提供原型的函数指针,因此将与具有不同数字甚至不同类型参数的函数兼容:
void (*insert)();
但是指向的任何函数都是通过这样的指针调用的函数-您将不会基于参数列表选择不同的函数。此外,参数将接受默认参数提升,并且提升后的参数必须在类型和数量上与实际函数参数一致。
如果指针声明确实提供了原型,并且您通过它调用了指向函数,则该函数必须具有兼容的签名,因为在语言规范中定义了“兼容”。特别是可变参数和非可变函数声明彼此不兼容,因此,用可变参数原型声明指针的想法是不一致的。
因此,它实际上与结构无关。相反,问题在于函数指针。您可以应用您描述的宏技巧来在多个函数指针中进行选择,或者可以编写可变参数包装函数来执行这种选择,但是不能将这种选择编码到指针本身中。
答案 1 :(得分:0)
您可以为.insert
函数指针赋予任意类型(如果您使用void (*)()
之类的东西,则采用非短参数或可变参数的void重现函数将转换为该指针类型隐式,但这不是必须的),然后有一个INSERT(&myarray, ...)
宏来对参数进行计数,根据计数将.insert
转换为适当的类型,然后调用它。