匿名函数返回动态分配的值 [英] Anonymous functions return dynamically allocated values

查看:150
本文介绍了匿名函数返回动态分配的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结:基本上是一个Runner,它接收指向它缓存的多态工厂方法的指针,稍后调用实例化并在事件发生时执行。

为了便于传达,我创建了一个包含源文件和测试文件的小型独立项目。 下载



运行 make 来编译



运行 make test 运行测试



希望这有助于您。






这个问题是基于一种设计模式解决方案,很容易在其他语言中使用,但很难在C中实现。缩小的代码在下面。



基于链接的答案我试图找到一个匿名函数动态生成的值的解决方案。

摘自答案:

  int(* max)(int,int)= 
({
int __fn__(int x,int y){return x> y?x:y;}
__fn__;
});

静态图书馆代码

  struct Super {
}

void add(struct Super *(* superRef)()){
// cache在某个事件发生的某个时刻,引用(在某个链表中)

// //。
struct Super * super = superRef(); //实例化并使用它。
}

链接的客户端代码:库代码的用户

  struct Sub {
struct Super * super;

$ b $($ {$ b $ struct struct Sub __fn __(){return malloc(sizeof(struct Sub));} //错误
__fn__;
}));

错误:

 错误:将'void'传递给不兼容类型的参数struct Sub *(*)()

根据请求澄清,请考虑接收对结构对象(非实例化)的引用的静态库文件中的接收函数。其次,客户端或静态库库不会立即实例化接收到的结构引用。稍后当系统中有通知时,将调用结构引用来实例化并执行其余的东西。

我重复一遍,具体要求是保存对库(用户代码)用户传递的结构的非实例化引用。希望这个清除。

解决方案

经过很多努力,这里有解决方案,但感谢社区的帮助。
$ b

第一个社区告诉我,匿名函数不是C的一部分,所以另一种建议是使用命名函数和指针。

其次,指向父结构体的指针不能接收指向其派生类型(嵌入式父结构体)的指针,所以我不能在那里做很多事情。我尝试过使用 void * ,但是也许一个解决方案可能会使用内存地址,然后访问该结构的某个成员而不投射到特定类型。我会问另一个问题。



我缺少的是以某种方式从重写的run方法调用super方法的能力?



src / super.h $ b

  struct Super { 
void(* run)();
};

struct Super * newSuper();

src / super.c

  static void run(){
printf(Running super struct\\\
);

$ b $ struct Super * newSuper(){
struct Super * super = malloc(sizeof(struct Super));
super-> run = run;
返回超级;
}

src / Runner.h

  struct Runner {

void(* addFactoryMethod)(struct Super *(* ref)());

void(* execute)();
};

struct Runner * newRunner();

src / runner.c

  struct Super *(* superFactory)(); 

void addFactoryMethod(struct Super *(* ref)()){
superFactory = ref;


static void execute(){
struct Super * sup = superFactory(); //调用缓存的工厂方法
sup-> run();

$ b $ struct Runner * newRunner(){
struct Runner * runner = malloc(sizeof(struct Runner));
runner-> addFactoryMethod = addFactoryMethod;
runner-> execute = execute;
回归亚军;

test / runner_test.c

  void anotherRunMethod(){
printf(polymorphism working \\\
);
//我怎么能够在这里调用重写的超级方法?

$ b $ struct Super * newAnotherSuper(){$ b $ struct Super * super = malloc(sizeof(struct Super));
super-> run = anotherRunMethod;
返回超级;
}

void testSuper(){
struct Runner * runner = newRunner();
runner-> addFactoryMethod(&newAnotherSuper);
runner-> execute();
}

int main(){
testSuper();
返回0;
}


Edit

Summary: Basically a Runner that receives pointer to a polymorphic factory method which it caches and later calls to instantiate and executes when an event occurs.

To make things easier to convey, I've created a small isolated project with source and test files. Download

Run make to compile

Run make test to run test

Hope this helps.


The question is based on a design pattern solution easily doable in other languages but difficult to implement in C. The narrowed down code is below.

Building on the linked answer I'm trying to find a solution for the dynamically generated values in an anonymous function.

Excerpt from the answer:

int (*max)(int, int) =
({
    int __fn__ (int x, int y) { return x > y ? x : y; }
    __fn__;
});

Static Library Code

struct Super{
}

void add(struct Super *(*superRef)()) {
    // cache the reference (in some linked list)

    // later at some point when an event occurs.
    struct Super *super = superRef(); // instantiate and use it.
}

Client Code linked: User of the Library Code

struct Sub{
     struct Super *super;
}

add(({
    struct Sub __fn__() { return malloc(sizeof(struct Sub)); } // error
    __fn__;
}));

Error:

error: passing 'void' to parameter of incompatible type 'struct Sub *(*)()

As per the request for clarification, think of the receiving function in a static library file receiving references to the structure objects (non-instantiated). The lib receives this object from the client code.

Secondly the client or static library library doesn't instantiate the received structure reference right away. Later when there's a notification in the system, the structure reference is called to instantiate and execute the rest of the stuff.

I repeat, The specific requirement is to hold non-instantiated references to the structures passed by users of the library (client code). Hope this clears.

解决方案

After much struggle, Here's the solution but thanks to community for the help.

First community told me that anonymous functions are not part of C, so the alternate suggestion is to use named functions and pointer to it.

Secondly a pointer to a parent struct can't receive a pointer to it's derived type (Embedded parent struct) so I can't do much there. I tried using void * but perhaps a solution might exists using memory address and then access some member of the struct without casting to specific types. I'll ask that in another question.

What I'm missing is the ability to call the super method from the overridden run method in some way?

src/super.h

struct Super {
    void (*run)();
};

struct Super *newSuper();

src/super.c

static void run() {
    printf("Running super struct\n");
}

struct Super *newSuper() {
    struct Super *super = malloc(sizeof(struct Super));
    super->run = run;
    return super;
}

src/Runner.h

struct Runner {

    void (*addFactoryMethod)(struct Super *(*ref)());

    void (*execute)();
};

struct Runner *newRunner();

src/runner.c

struct Super *(*superFactory)();

void addFactoryMethod(struct Super *(*ref)()) {
    superFactory = ref;
}

static void execute() {
    struct Super *sup = superFactory(); // calling cached factory method
    sup->run();
}

struct Runner *newRunner() {
    struct Runner *runner = malloc(sizeof(struct Runner));
    runner->addFactoryMethod = addFactoryMethod;
    runner->execute = execute;
    return runner;
}

test/runner_test.c

void anotherRunMethod() {
    printf("polymorphism working\n");
    // how can i've the ability to call the overridden super method in here?
}

struct Super *newAnotherSuper() {
    struct Super *super = malloc(sizeof(struct Super));
    super->run = anotherRunMethod;
    return super;
}

void testSuper() {
    struct Runner *runner = newRunner();
    runner->addFactoryMethod(&newAnotherSuper);
    runner->execute();
}

int main() {
    testSuper();
    return 0;
}

这篇关于匿名函数返回动态分配的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆