【问题标题】:C function that allows two data types允许两种数据类型的 C 函数
【发布时间】:2021-01-14 14:04:35
【问题描述】:

也许这只是一个愚蠢的问题,但我想知道是否有一种方法可以在同一个函数参数中允许两种数据类型,一种最终做同样事情的多态性,只是为了过滤掉一些垃圾输入。

typedef enum
{

} type1_t;

typedef enum
{

} type2_t;

void myfunc(typex_t foo)
{

}

【问题讨论】:

  • 简短回答:不。C 是一种强类型语言。长答案:有点像void* 和很多巫毒教,但这与“过滤掉垃圾”的效果相反,因为它可以让任何东西进入。
  • 你可以使用union吗?
  • 你不能只使用一个函数。但是,您可以使用宏和 generic selection 根据类型调用两个函数之一。
  • 如果只是枚举,则可以使用 int。但无论如何,您都需要一种方法来知道传递了什么类型,不是吗?
  • 你想用这个解决什么问题?也许这是XY Problem(我可能错了)。你会如何处理myfunc 中的fooEdit 并显示扩展您的示例。

标签: c types


【解决方案1】:

您可以考虑另一种方法,其中涉及 C11 功能之一。

一个generic selection

提供一种在编译时根据控制表达式的类型选择多个表达式之一的方法。

你最终会得到一些代码重复,但也是一个通用的“接口”。

#include <stdio.h>

void myfunc_int(int x){
    printf("int: %d\n", x);
}
void myfunc_float(float y){
    printf("float: %f\n", y);
}

#define myfunc(X) _Generic((X),     \
    int : myfunc_int,               \
    float : myfunc_float            \
) (X)

int main(void)
{
    myfunc(3.14f);

    myfunc(42);

//    myfunc(1.0);
//           ^ "error: '_Generic' selector of type 'double'
//                    is not compatible with any association"
}

可测试here

【讨论】:

  • 虽然看起来很有效,但代码重复是为这样的事情付出的巨大代价
【解决方案2】:

标记联合

你可以使用联合:

typedef union
{
    type1_t t1;
    type2_t t2;
} UnionType;

您需要以某种方式知道t1t2 是否处于活动状态。为此,您可以传递一个额外的枚举值(您要允许的每种类型的不同值):

enum types
{
    TYPE1,
    TYPE2
};

将它组合到一个结构中,你就有了 typex_t:

typedef struct
{
    enum types type; // this is also called a type tag
    UnionType content;
} typex_t;

或更紧凑(非标准)

typedef struct
{
    enum { TYPE1, TYPE2 } type;
    union { type1_t t1; type2_t t2; } content;
} typex_t;

整个struct union 构造也称为标记联合。

【讨论】:

  • 在现代 C 中你可以匿名 union { type1_t t1; type2_t t2; };。但是在现代 C 中,您可能会使用 _Generic 而不是过去的旧枚举技巧。
猜你喜欢
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
相关资源
最近更新 更多