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

C++ 什么是void(*op)(T&;)和void(*op)(T&;,void*)?,c++,templates,parameters,linked-list,C++,Templates,Parameters,Linked List,我有一个关于链表和模板的作业,其中有带有奇怪参数的函数,这些参数是必需的。 我找不到关于它的在线文档,请提供任何资料 我试着给op分配另一个地址,然后它编译得很好,但我不能调用它 template <class T> struct L1Item { T data; L1Item<T> *pNext; L1Item() : pNext(NULL) {} L1Item(T &a) : data(a), pNext(NULL) {} }; templa

我有一个关于链表和模板的作业,其中有带有奇怪参数的函数,这些参数是必需的。 我找不到关于它的在线文档,请提供任何资料

我试着给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;
    //    };
  }
};
模板结构L1项{
T数据;
l1项目*pNext;
L1Item():pNext(NULL){}
L1Item(T&a):数据(a),pNext(NULL){}
};
模板类列表{
L1Item*\u pHead;//链表的头指针
size\u t\u size;//此列表中的元素数
公众:
无效导线(无效(*op)(T&){
//TODO:您的代码在这里
}
无效导线(无效(*op)(T和,无效*),无效*pParam){
//TODO:您的代码在这里
//字符串*Req=静态转换(pParam);
//如果(*Req==“查找城市id”){
//op=此->\u pHead;
//    };
}
};
代码
void(*op)(T&)
op
声明为指向函数的指针,函数引用类型
T
作为参数
void(*op)(T&,void*)
类似,但有一个类型为
void*
的额外参数

与其在(注释掉的)代码中尝试将指向对象的指针分配给它,
op=this->\u 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
}
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);
// ...
void traverse( void op( T & ) ) {
    // TODO: Your code goes here
}
在代码的其他地方,当您实际调用
遍历
时,您需要给出您(或某人)定义的函数的地址,作为它的第一个参数;例如:

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
}
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);
// ...
void traverse( void op( T & ) ) {
    // TODO: Your code goes here
}
模板void myFunc(T&obj,void*pParam){
字符串*Req=静态转换(pParam);
如果(*Req==“查找城市id”){
//对“obj”做点什么
}
}
//...
导线测量(myFunc、pString);
// ...
请随意要求进一步解释(但也请阅读问题中给出的评论)

这是:

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(*)(T&)

如果不是函数指针,而是函数类型,则声明看起来更简单,例如:

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
}
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);
// ...
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遍历(void(*op)(T&,void*),void*pParam){
//TODO:您的代码在这里
//字符串*Req=静态转换(pParam);
//如果(*Req==“查找城市id”){
//op=此->\u 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;
   //    };
}
void遍历(void op(T&,void*),void*pParam){
//TODO:您的代码在这里
//字符串*Req=静态转换(pParam);
//如果(*Req==“查找城市id”){
//op=此->\u pHead;
//    };
}

这使得声明更加清晰。

相关:试图为函数指针的dupeSearch找到更好的目标。这是来自C(以及C++的一些内容)对英语来说,这是令人惊讶的,有人会给你这个作业而不曾解释函数指针语法。RANT:有时候我很惊讶老师在教学C++方面有多差。我认为这是朗格没有被广泛使用的原因之一。就好像有些教师在教C的时候,用“类”(实际上是第一个C++版本之一)而不是C++。如果你给某人上Java课程,开始教他们字节码(即使老师可能非常熟悉字节码)是愚蠢的。也许不是一个好例子,但你明白我的意思。应该是另一种方式!它是一个指向函数的指针,需要有一个它指向的函数。在这种情况下,需要在遍历()时传入函数called@DanS谢谢你的评论!我已经扩大了我的答案以纳入你的建议。