【问题标题】:How do I create a C factory function?如何创建 C 工厂函数?
【发布时间】:2010-12-13 15:05:19
【问题描述】:

我有一个带有函数指针的结构,如下所示:

typedef int (*node_transition_func)( wint_t );

typedef struct lex_dfa_arc_t {

    node_transition_func func;
    int expected_return_val;
    struct lex_dfa_node_t * node;

} LEX_DFA_ARC_T;

现在我想创建一个返回原型函数“int func(wint_c);”的函数例如:

node_transition_func input_equals( wint_t input, wint_t desired ) { ... }

在 C 中是否有可能让上面的函数真正起作用?我试图避免为每个字母定义一个函数(例如 input_equals_letter_a、input_equals_letter_b、input_equals_letter_c 等)。

我的另一种方法是让 node_transition_func 接收所需字符的 wint_t 和 wchar_t*,但我很好奇我的第一种方法是否可行。

谢谢!

【问题讨论】:

标签: c


【解决方案1】:

您基本上可以模拟闭包和柯里化,而不是“返回一个函数”,而是返回一个具有函数指针和绑定变量的结构。加上几个#defines,它甚至可能看起来还算正常。

OTOH,当你使用一种特定的语言时,你应该坚持它的成语。闭包不是 C 的强项。我建议您不要尝试在 C 代码中过于通用,如果有疑问,只需使用 switch(){}。

【讨论】:

    【解决方案2】:

    您不能在 C 中动态创建新函数。由于它是一种编译语言,并且编译器不是标准运行时的一部分,因此所有代码都必须在编译时静态定义。

    【讨论】:

    • 实际上这不是 100% 正确的。您可以让自己的迷你编译器生成编译代码(可能来自预定义的编译代码构建块),将其粘贴在内存中的某个位置,然后调用它。当然取决于内核对内存使用的限制。但是,如果您想编写自更改代码,也许像 LISP 这样的另一种语言可能更合适。
    【解决方案3】:

    看起来您正在尝试在 C 中进行柯里化(cue clippy :-)。我认为这在 C 中在技术上是可能的。您不是在尝试创建新功能。您正在尝试为现有函数创建替代绑定。这在 C++ 中非常简单,但是如果没有模板元编程(特别是函子和绑定)所提供的语法糖,您将不得不手动完成所有这些工作。您的其他方法似乎更合理。

    【讨论】:

      【解决方案4】:

      我猜你的这个函数会遍历 LEX_DFA_ARC_T 列表并返回匹配元素的“func”成员?

      没有理由不这样做。毕竟像 node_transition_func 这样的函数指针仍然只是一个指针。也就是说,这可能不是最好的解决方案。

      但是,由于您所说的其他内容,我对我的猜测是否正确感到有些困惑。也许更多的上下文可能会帮助我们回答你。

      【讨论】:

        【解决方案5】:

        这可能是您在 C 语言中最接近于柯里化的方法:

            int input_equals_with_type(wint_t Input, wint_t desired) {
                // Do some stuff with regard to different type of "desired"
                return 1;
            }
        
            #define MAKE_NODE_TRANS_FUNC(type, wint_t desired) \
                int node_transition_func_##type(wint_t input) { \
                    return input_equals_with_type(input, desired); \
                }
        
            MAKE_NODE_TRANS_FUNC(letter_a, letter_a_disired)
            MAKE_NODE_TRANS_FUNC(letter_b, letter_b_desired)
            // and so on...
        

        这里的限制当然是这不是“真正的”柯里化,因为函数是在编译时创建的,而不是在运行时创建的。但是,如果您只是尝试制作几种类型的函数,那么这是可行的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-16
          • 1970-01-01
          • 2016-02-13
          • 1970-01-01
          • 2018-01-10
          • 1970-01-01
          • 2022-06-11
          相关资源
          最近更新 更多