Что такое void (* op) (T &) и void (* op) (T &, void *)? - PullRequest
2 голосов
/ 25 сентября 2019

У меня есть задание о связанном списке и шаблоне, где есть функции со странными параметрами, которые являются обязательными.Я не смог найти в интернете документ об этом, и любые предоставленные материалы приветствуются.

Я попытался назначить операцию с другим адресом, а затем она просто скомпилировалась, но я не смог ее назвать.

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;
    //    };
  }
};

Ответы [ 2 ]

4 голосов
/ 25 сентября 2019

Код 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);
// ...

Не стесняйтесь спрашивать дальнейшие объяснения (но также читайте комментарии, приведенные в вашем вопросе)!

0 голосов
/ 25 сентября 2019

This:

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

- это объявление функции, в котором есть один параметр указателя на тип функции void ( * )(T &).

Объявление будет выглядеть более простым, если вместо указателя функциибудет тип функции, например:

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

Компилятор неявно преобразует тип функции в указатель на тип функции.

This:

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;
   //    };
}

Это делает объявление более понятным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...