【问题标题】:Limit an argument of a function to an enum type only将函数的参数限制为仅枚举类型
【发布时间】:2021-08-26 12:35:56
【问题描述】:

我有一个枚举 day_t,其中包含星期几。

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

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

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

setDay(day.wednesday);

谢谢。

【问题讨论】:

  • 这不是 C 的一个特性。对于代码编写自动完成问题,您可以使用一个结构来伪造它,其中元素与其枚举值具有相同的名称,但这不是一个好的解决方案。如果这很重要,您可能需要考虑 C++,它是 enum class。至于限制参数值,这只是你必须在函数本身中检查的内容。
  • C 标准没有为此提供功能。部分由于 C 开发方式的历史原因,enum 类型主要是整数类型,并且可以与其他整数类型互换使用。它们之间的分离很弱。在少数情况下,特定的编译器可能会提供一些额外的功能来警告您。
  • day.wednesday 不是有效的 C,所以你不能这样做。您可能必须使用结构包装器等来在某些 IDE 中完成代码。

标签: c enums


【解决方案1】:

使用How to create type safe enums? 中的技巧可以做到这一点,采用接受的答案中描述的类型安全赋值技巧:

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
}

【讨论】:

    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多