将函数的参数限制为仅枚举类型

Limit an argument of a function to an enum type only

我有一个包含星期几的枚举 day_t

typedef enum
{
    monday = 1,
    tuesday,
    wednesday,
    thursday,
    friday,
    saturday,
    sunday
} day_t;

我想用枚举定义(友好名称)限制函数setDay(someType Day)的参数。是否可以使用枚举或其他方式?

例如,我想在代码中输入这样的参数,智能感知允许我看到其他友好名称:

setDay(day.wednesday);

谢谢。

可以通过使用 接受的答案中描述的类型安全分配的技巧来做到这一点:

typedef union
{
  day_t monday;
  day_t tuesday;
  day_t wednesday;
  day_t thursday;
  day_t friday;
  day_t saturday;
  day_t sunday;
} typesafe_day_t;

#define day_assign(var, val) _Generic((var), day_t: (var) = (typesafe_day_t){ .val = val }.val)

然后给定一些函数void set_day (day_t day),我们可以使用包装器宏设计一个安全版本:

#define set_day_s(day) set_day( day_assign((day_t){0},day) )

这会创建一个传递参数的临时副本,并通过类型安全宏运行它,阻止所有不是提到的枚举常量之一的内容。

完整示例:

typedef enum
{
  monday = 1,
  tuesday,
  wednesday,
  thursday,
  friday,
  saturday,
  sunday
} day_t;

typedef union
{
  day_t monday;
  day_t tuesday;
  day_t wednesday;
  day_t thursday;
  day_t friday;
  day_t saturday;
  day_t sunday;
} typesafe_day_t;

#define day_assign(var, val) _Generic((var), day_t: (var) = (typesafe_day_t){ .val = val }.val)

void set_day (day_t day){ /* ... */ }
#define set_day_s(day) set_day( day_assign((day_t){0},day) )

int main (void)
{
  set_day_s(monday); //  OK

  day_t d=monday;
//  set_day_s(d);      // compiler error
//  set_day_s(1);      // compiler error
}