【问题标题】:Is it possible to define a function using a callback type definition?是否可以使用回调类型定义来定义函数?
【发布时间】:2019-11-05 13:12:10
【问题描述】:

我对使用预定义的回调类型定义函数感兴趣。

假设我已经定义了回调类型:

typedef BOOL (*is_trigger_required_cb)(void);

现在我想使用上述类型声明和定义一个函数。

我想做这样的事情:

is_trigger_required_cb my_func { /* function implementation which accepts void and returns BOOL */ }

由于以下原因无法编译:

错误:预期为 ';'在顶级声明符之后

据我了解,这是不可能的,因为编译器仅将回调类型称为类型安全的函数指针,不能用于函数定义。如果回调类型发生变化,它会破坏编译,从而保持类型安全。

【问题讨论】:

    标签: c callback


    【解决方案1】:

    typedef is_trigger_required_cb 不是函数类型的别名,而是指向函数的指针。另外C11 6.9.1p2

    在函数定义中声明的标识符(它是函数的名称)应具有函数类型,由函数定义的声明符部分指定。 [162]

    脚注 162 表示

    162) 意图是函数定义中的类型类别不能继承自 typedef[...]

    即你不能这样做 - 原因很明显 - 函数 type 没有 name 参数,因此它不能用于在函数体内声明参数。

    【讨论】:

      【解决方案2】:

      如果你定义 function 类型,你可以近似它。

      typedef BOOL is_trigger_required_cb(void);
      

      这将使回调成为一个显式指针(我认为这是一个加号)

      is_trigger_required_cb *cb;
      

      并且将允许您至少声明具有该类型的函数:

      is_trigger_required_cb my_func;
      BOOL my_func (void) {
        // Do stuff
      }
      

      您仍然需要在定义点重复完整的原型,这是无法绕过的,因为语法迫使您动手。但至少你得到了你所追求的类型检查,因为声明必须与原型函数的定义相匹配。

      然而,它可能看起来很神秘,因为这不是人们通常看到的东西。我建议你权衡一下它的优点和解释它的必要性。

      【讨论】:

        【解决方案3】:

        不,你不能那样做。您只能将这些 typedef 用于函数指针。您可以像 Storyteller 在他们的答案中那样定义一个函数类型。但正如你所看到的,它并没有真正让事情变得更好。我的解决方案也没有。

        使用宏(不,不要这样做)

        你可以做的一件事,但我强烈反对它,就是使用宏:

        #define f(fname) BOOL fname (void)
        
        f(foo) {
            return 1;
        }
        

        上面会给你一个函数foo,它接受零参数并返回一个BOOL。不过,它会带来很多限制。如果你想支持论点,你可以这样做:

        #define binary_bool(fname, arg1, arg2) BOOL fname (arg1, arg2)
        
        binary_bool(equals,x,y) {
            return x==y;
        }
        

        再次,我建议不要这样做。我只是在证明与您想要的类似的东西在理论上是可能的。像这样的宏通常会使调试变得非常棘手。

        TL;DR

        不,你不能在 C 中很好地做到这一点

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-24
          • 2016-10-25
          • 2012-05-30
          • 1970-01-01
          • 2011-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多