【问题标题】:Function overloading inside a C99 structC99 结构内的函数重载
【发布时间】:2019-07-07 17:21:07
【问题描述】:

通常,在 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) 来打印100 时,C99 不会抱怨传递给... 的零参数,我希望我的程序与C99 完全兼容)

但问题是:pr 不是函数,所以不能赋值给结构体内部的函数指针:

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

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

【问题讨论】:

  • 对不起,但这似乎是灾难的根源。为什么不直接将正确的函数分配给你的结构呢?
  • 我认为这将是一个不错的接口:我可以避免其他数据类型版本之间的名称差异。例如:我有intfloat 版本:我只是调用myarray.insert(...) 而不是insert_int(&myarray, ...)insert_float(&myarray, ...)
  • 对,您可以通过将您想要的版本显式分配给结构中的指针来实现。重载只会混淆。
  • 此外,类型安全存在 var-args 问题,这会让我犹豫是否真的需要这样做。 C11 引入_Generic;它可能是您正在寻找的。​​span>

标签: c function struct c99


【解决方案1】:

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

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

void (*insert)();

但是任何指向的函数都会通过这样的指针被调用——你不会根据参数列表选择不同的函数。此外,参数将受到默认参数提升的影响,并且提升的参数必须在类型和数量上与实际的函数参数一致。

如果您的指针声明确实提供了原型,并且您通过它调用指向的函数,那么该函数必须具有兼容的签名,因为“兼容”在语言规范中定义。尤其是可变参数和非可变参数函数声明相互不兼容,所以你用可变参数原型声明指针的想法是不符合标准的。

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

【讨论】:

    【解决方案2】:

    你可以给.insert函数指针一个任意类型(如果你使用类似void (*)()的东西,那么接受非短或可变参数的void-return函数将隐式转换为该指针类型,但是不是必需的)然后有一个 INSERT(&myarray, ...) 宏来计算参数,根据计数将 .insert 转换为适当的类型,然后调用它。

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 2020-11-28
      相关资源
      最近更新 更多