void (*op)(T &) 和 void (*op)(T &, void *) 是什么?

3

我有一个关于链表和模板的作业,其中有些函数有奇怪的必需参数。

我找不到相关的在线文档,非常感谢提供任何资料。

我尝试将op分配给另一个地址,然后它成功编译了,但是我无法调用它。

template <class T> struct L1Item {
  T data;
  L1Item<T> *pNext;
  L1Item() : pNext(NULL) {}
  L1Item(T &a) : data(a), pNext(NULL) {}
};

template <class T> class L1List {
  L1Item<T> *_pHead; // The head pointer of linked list
  size_t _size;      // number of elements in this list
public:
  void traverse(void (*op)(T &)) {
    // TODO: Your code goes here
  }
  void traverse(void (*op)(T &, void *), void *pParam) {
    // TODO: Your code goes here
    //    string *Req = static_cast<string *>(pParam);
    //    if (*Req == "find city's id") {
    //        op = this->_pHead;
    //    };
  }
};

3
好的,我会尽力完成您的翻译要求。以下是需要翻译的内容:related: https://dev59.com/9nE85IYBdhLWcg3w1HGF Trying to find a better target for a dupe - NathanOliver
3
搜索“函数指针”。 - Some programmer dude
2
有一个从C语言(以及部分C++)翻译成英语的翻译器 - Yksisarvinen
5
没想到有人会在没有先解释函数指针语法的情况下给你这个任务,这真是太神奇了。 - Useless
3
抱怨:有时候我很惊讶教授C++的老师有多么差。我认为这是导致该语言没有更广泛使用的原因之一。就好像有些老师在教“带类的C”(实际上,最早的C++版本之一就是这么叫的),而不是真正的C++。如果你给别人一门Java课程,开始教他们字节码是疯狂的(即使老师可能非常擅长字节码)。也许不是一个好例子,但你明白我的意思。应该反过来! - darune
显示剩余2条评论
2个回答

6
代码 void (*op)(T &) 声明 op 为一个函数指针,该函数接受类型 T 的引用作为参数;void (*op)(T &, void *) 类似,但有一个额外的类型为 void* 的参数。

在你(被注释掉的)代码中尝试将一个对象的指针赋值给它时,op = this->_pHead; 你应该调用传递的函数。例如,像这样:

void traverse(void (*op)(T &, void *), void *pParam) {
// TODO: Your code goes here
    op(pHead->data, pParam); // First parameter is a T passed by reference
}

在您的代码中的其他地方,当您实际调用traverse时,您需要提供它的第一个参数(的地址),这个参数是一个函数,您(或别人)已经定义过,例如:

template <class T> void myFunc(T& obj, void *pParam) {
    string *Req = static_cast<string *>(pParam);
    if (*Req == "find city's id") {
    // do something with/to "obj"
    }
}
//...
traverse(myFunc, pString);
// ...

随时询问进一步的解释(但也要阅读在您问题中提供的评论)!


1
这是一个指向函数的指针,需要有一个它所指向的函数。在这种情况下,当调用traverse()时,需要传入该函数。 - DanS
@DanS 感谢您的评论!我已经扩展了我的答案,以包含您的建议。 - Adrian Mole

1
这个:
void traverse(void (*op)(T &)) {
  // TODO: Your code goes here
}

这是一个函数声明,有一个指向函数类型 void (* )(T&) 的参数。

如果使用函数类型而不是函数指针,则声明会更简单,例如:

void traverse( void op( T & ) ) {
    // TODO: Your code goes here
}

编译器会将函数类型隐式转换为指向该函数类型的指针。
这个:
void traverse(void (*op)(T &, void *), void *pParam) {
    // TODO: Your code goes here
    //    string *Req = static_cast<string *>(pParam);
    //    if (*Req == "find city's id") {
    //        op = this->_pHead;
    //    };
}

这也是一个函数声明,有两个参数,第一个参数是指向函数类型的指针。

同样地,可以声明一个函数类型的参数,而不是一个函数指针:

void traverse( void op(T &, void *), void *pParam ) {
   // TODO: Your code goes here
   //    string *Req = static_cast<string *>(pParam);
   //    if (*Req == "find city's id") {
   //        op = this->_pHead;
   //    };
}

这使声明更清晰。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接