c - 您可以在 C 中进行重载并具有相同的函数名吗?
问题描述
在 Java 中,当方法具有相同名称时,我们可以进行重载。我在谷歌上搜索,它说 C 不支持重载,所以我想知道有没有办法在 C 中做类似于重载的事情。
例如:
int max(int num1, int num2);
double max(double num1, num2);
int main(){
printf(...);
printf(...);
}
int max(int num1, int num2){
...
}
double max(double num1, double num2){
...
}
解决方案
您找到的参考是正确的:C 不支持重载,因此。
它所拥有的(假设我们谈论的是实际的 C 而不是历史版本)是一个通用选择器,它允许您编写自己的宏来进行动态调度。
C99 引入了tgmath.h
标头,它允许重载某些数学函数以使用不同宽度的浮点参数,在某些情况下还可以使用复杂的参数。但是,C99 中没有引入任何工具来允许将该功能推广到其他功能。C11 中引入的通用选择器就是该工具。
选择器的格式为_Generic(select-expression, type-associations)
,其中type-associations
包含以逗号分隔的格式对列表type : expression
。选择器将被替换为与 的类型对应的表达式select-expression
。s之一type
可以是关键字default
;其他的必须是唯一的完整类型(即列表中没有两种类型可以兼容)[注1]。需要注意的是,关联列表中的所有表达式都必须正确编译,而不仅仅是最终选择的那个。通常,表达式将是函数指针,而不是函数调用。
一个例子可能会更清楚地说明这一点。假设我们有两个函数(名称不同,所以这不是名称重载):
int max_int(int a, int b) { return a > b ? a : b; }
double max_dbl(double a, double b) { return a > b ? a : b; }
现在,我们可以定义宏 MAX:
#define MAX(a, b) _Generic((a)+(b), \
int : max_int, \
double : max_dbl)(a, b)
在这里,我将a+b
其用作选择器表达式而不是a
,因为 ofa+b
的类型是由通常的算术转换产生的类型。如果我刚刚使用a
,那么MAX(3, 5.7)
会产生一个意想不到的结果,因为通用选择器会被选中max_int
并且5.7
会被默默地截断为 5。使用a+b
,选择器的类型将是double
,导致调用max_dbl
,这两个值都是转换为双倍。
我可以(a)+(b)
在宏中使用,因为_Generic
不评估选择器表达式(如sizeof
)。因此,不存在对具有副作用的论点进行双重评估的危险。
笔记:
- 通用关联的类型不能是 VLA(可变长度数组),即使编译器实现了它们。但是任何其他完整类型都可以,即使是指向不完整类型的指针。
推荐阅读
- rx-java2 - @RawQuery 和生成的 RxRoom.createFlowable(db, tables)
- azure - 如何将 docker 卷传输到 azure 中的 kubernetes 卷?
- java - 为什么我们不覆盖 Spring CRUD Repository 中的方法
- python-3.x - tensorflow教程中的基本分类
- json - 将 XML 转换为 JSON 的奇怪结果
- r - 从 violinboxplot 的子集标题中删除 facet.by 标签
- android - 对按钮进行编程以获得下一个焦点
- angular - 如何在 ionic 3 中使用 Observables
- javascript - 在获取用户时使用 Passport-jwt 时 req.user 未定义
- android - 当用户打开抽屉时调用函数(onClick 按钮或幻灯片)