Как решить перегруженную функцию без контекстной ошибки типа информации? - PullRequest
2 голосов
/ 26 марта 2019

Я делаю программу о двусвязном списке. У меня есть функция find, которая помогает найти, если таковой нет. 7 находится где-нибудь в этом списке. Эта функция работает нормально и возвращает указатель на этот узел.

Тогда у меня есть функция afterElement, которая вставляет, например, нет. 3 после № 7, поэтому он использует указатель на функцию find в качестве параметра. Я думаю, что отсюда и проблема, но я могу ошибаться, вы будете судьей.

Я хочу знать, как я могу правильно использовать эту функцию? Что-то не так с тем, как я передаю параметры или еще? Я получаю ошибку «перегружена функция без контекстной информации о типе».

Вот соответствующий код:

#include <iostream>
using namespace std;

struct node {
int data;
node* prev;
node* next;
};

node* find(int,node*&);
void afterElement(int,int,node*&,node*&,node* (*find)(int, node*&));

int main() {
    node* head = NULL;
    node* tail = NULL;
    // The program itself has a menu that allows for input of value in list but
    // for the sake of relevancy and shortness of code I dropped it out from here

    int x, y;
    cout << "Insert 2 values: value you wish to insert, and value you wish to insert it after. ";
    cin >> x;
    cin >> y;
    afterElement(x,y,head,tail,(*find)(y,head)); // here is the error "overloaded function..."
    return 0;
}

node* find(int x,node*& head) {
    node* curr = head;
    while ((curr != NULL) && (curr->data != x))
        curr = curr->next;
    return curr;
}

void afterElement(int x,int after,node*& head,node*& tail,node* (*find)(int x, node*& head)) {
node* N;
node* compared = (*find)(after,head);
N->data = x;
if (compared == NULL)
    cout << "There is no element " << after << " in the list!\n";
else {
    if (compared->next == NULL) {
        compared->next = N;
        N->prev = compared;
        N->next = NULL;
        tail = N;
    } else {
        compared->next->prev = N;
        N->next = compared->next;
        compared->next = N;
        N->prev = compared;
    }
}
}

Ответы [ 2 ]

0 голосов
/ 26 марта 2019

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

afterElement(x,y,head,tail,find); 

Это минимальное исправление, которое приводит к компиляции вашей программы. Живая демоверсия . Обратите внимание, это только показывает, что ошибки компиляции исправлены, а не то, что программа работает!

Кроме того, поскольку вы using namespace std, вы получаете непонятные сообщения об ошибках, поскольку компилятор не может выяснить, что find вы имеете в виду, свое или std::find. Если вы избавитесь от using namespace std, ваше сообщение об ошибке станет намного понятнее:

error: cannot convert ‘node*’ to ‘node* (*)(int, node*&)’

Живая демоверсия . Никогда не используйте using namespace std.

Однако вы можете рассмотреть возможность удаления find из списка параметров afterElement. afterElement не нужно указывать, какую функцию вызывать, чтобы найти элемент.

void afterElement(int x,int after,node*& head,node*& tail)

будет работать просто отлично.

Передача указателя на узел вместо int after также будет работать:

void afterElement(int x, node* after, node*& head, node*& tail)

Позвоните afterElement(x, y, find(x, head), head, tail), чтобы использовать этот вариант. Обратите внимание, вам не нужно говорить (*find)(x, head).

С вашим кодом больше проблем, чем с этой ошибкой компиляции. Например

node* N;
...
N->data = x;

неверно. Вы не инициализировали N, он никуда не указывает, поэтому вы не можете использовать -> для него.

Другая проблема заключается в том, что ваша программа никогда не изменяет head, поэтому в списке нет шансов что-либо содержать. Возможно, это нужно исправить, добавив больше функций (например, beforeElement).

0 голосов
/ 26 марта 2019

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

Конечно, вы можете передать функцию в качестве аргумента другой функции.Функция также сохраняется в ячейке памяти.Эта ячейка памяти хранится в переменной с именем, совпадающим с именем функции (в данном случае «find»).

Теперь вы получаете аргумент функции find в качестве указателя в функции afterElement, поэтому он ожидает адрес, но вы передаете всю функцию.Это причина, почему он выдает ошибку компиляции.Правильный код выглядит следующим образом:

#include <iostream>using namespace std;

struct node {
int data;
node* prev;
node* next;
};

node* find(int,node*&);
void afterElement(int,int,node*&,node*&,node* (*find)(int, node*&));

int main() {
    node* head = NULL;
    node* tail = NULL;
    // The program itself has a menu that allows for input of value in list but
    // for the sake of relevancy and shortness of code I dropped it out from here

    int x, y;
    cout << "Insert 2 values: value you wish to insert, and value you wish to insert it after. ";
    cin >> x;
    cin >> y;
    afterElement(x,y,head,tail,find); // modified the passing argument
    return 0;
}

node* find(int x,node*& head) {
    node* curr = head;
    while ((curr != NULL) && (curr->data != x))
        curr = curr->next;
    return curr;
}

void afterElement(int x,int after,node*& head,node*& tail,node* (*find)(int x, node*& head)) {
node* N;
node* compared = (*find)(after,head);
N->data = x;
if (compared == NULL)
    cout << "There is no element " << after << " in the list!\n";
else {
    if (compared->next == NULL) {
        compared->next = N;
        N->prev = compared;
        N->next = NULL;
        tail = N;
    } else {
        compared->next->prev = N;
        N->next = compared->next;
        compared->next = N;
        N->prev = compared;
    }
}
}

Я проверил с компиляцией, но проверьте один раз для ожидаемых результатов.Спасибо.

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