如何创建委托并将其作为参数传递到一行中

时间:2015-12-14 13:50:50

标签: c delegates

我已经实现了List,并且我还实现了ForEach方法,以便更轻松地进行迭代。

typedef struct node
{
    struct node* NextNode;
    void* Data;
} Node;

typedef struct list
{
    Node* Head;
    Node* Tail;
    int Length;
} List;

void ListForEach(List* list, void(*iteratorDelegate)(Node*))
{
    Node* actual = list->Head;
    while (actual)
    {
        iteratorDelegate(actual);
        actual = actual->NextNode;
    }
}

Node* NodeNew(void* data)
{
    Node* node = malloc(sizeof(Node));
    node->NextNode = NULL;
    node->Data = data;
    return node;
}

List* ListNew()
{
    List* list = malloc(sizeof(List));
    list->Head = NULL;
    list->Tail = NULL;
    list->Length = 0;
    return list;
}

我的Testprogramm看起来像这样:

void PrintDelegate(Node* node)
{
    printf("Data: %d\n", (int)node->Data);
}

int main(int argc, const char* argv[])
{
    List* list = ListNew();
    int counter = 0;
    for (counter; counter != 500000; counter++)
    {
        ListAdd(list, NodeNew((void*)counter));
    }

    ListForEach(list, PrintDelegate);
}

ListForEach的使用感觉非常不方便,因为我总是要创建一个新方法。是否有更简单的方法来委派方法? 在 C#我会这样做:

ListForEach(list, (node) => printf("Data: %d\n", (int)node.Data));

这也创建了一个委托,但我不需要在类/全局范围内声明一个新方法。

C 中也可以这样吗?

2 个答案:

答案 0 :(得分:1)

C语言没有lambda函数。但是,C ++确实从C ++ 11开始支持它。

因此,如果您愿意进行切换,您可以执行以下操作:

ListForEach(list, 
    [](Node* node) {
        printf("Data: %d\n", (int)node->Data);
    } // end of lambda expression
);

答案 1 :(得分:1)

Google搜索的定义"什么是C"中的代表:

  

C#中的委托类似于C或C ++中的函数指针。用一个   委托允许程序员封装对方法的引用   在委托对象中。然后可以将委托对象传递给   代码可以调用引用的方法,而不必知道   编译时将调用哪个方法。

强调我的

委托的概念在C本身不存在.C中最接近的是函数指针。使用函数指针,您可以定义要指向的几个方法,但是将实际方法选择推迟到运行时。 (即,您不必知道在编译时将使用哪种方法。)

一个简单的函数指针示例:

enum {
    ADD,
    SUB,
    MULT,
    DIV,
    OP_MAX
};

typedef float (*pOperation)(float x, float y);

pOperation Op[OP_MAX] = {0}; //create function pointer using typedef

//prototype various functions to use function pointer
float add(float x, float y);
float sub(float x, float y);
float mult(float x, float y);
float div(float x, float y);

int main(void)
{
    float res = 0;
    int i;

    //tie "delegate" to various implementations 
    Op[ADD] = &add;
    Op[SUB] = ⊂
    Op[MULT] = &mult;
    Op[DIV] = ÷

    for(i=ADD;i<OP_MAX;i++)
    {
        //here, Op is used as a delegate for each of the 4 basic arithmetic functions: 
        res = Op[i](3, 7); //performs 4 basic arithmetic functions

        //From definition above: The delegate object can 
        //be passed to code which can call the referenced method, 
        //without having to know at compile time which method 
        //will be invoked
    }

    return 0;
}

//implementations
float add(float x, float y){return x + y;}
float sub(float x, float y){return x - y;}
float mult(float x, float y){return x * y;}
float div(float x, float y){return x / y;}

ListForEach(list, PrintDelegate);也许可以以类似的方式实现(使用函数指针)来完成你需要做的事情。