问题
I'm doing a program about doubly linked list. I have function find that helps locate, if per se, no. 7 is anywhere within that list. This function works fine and returns pointer to that node.
Then I have function afterElement that inserts for example no. 3 after no. 7, So it uses pointer to find function as parameter. I think this is where the problem stems from, but I might be wrong, you be the judge.
I wanna know, how can I correctly use this function? Is there something wrong with how I pass parameters or else? The error I get is "overloaded function with no contextual type information".
Here is the relevant code:
#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;
}
}
}
回答1:
If you want to pass a function as an argument to another function, you just need to use the function name, not the entire call expression.
afterElement(x,y,head,tail,find);
This is the minimal fix that causes your program to compile. Live demo. Note this only demonstrates that the compilation errors are fixed, not that the program works!
In addition, because you are using namespace std, you are getting incomprehensible error messages, since the compiler cannot figure out what find you have in mind, your own or std::find. If you get rid of using namespace std, your error message becomes much clearer:
error: cannot convert ‘node*’ to ‘node* (*)(int, node*&)’
Live demo. Never use using namespace std.
However you may want to consider removing find from the parameter list of afterElement. afterElement doesn't need to be told which function to call in order to find an element.
void afterElement(int x,int after,node*& head,node*& tail)
would work just fine.
Passing a pointer to a node instead of int after will also work:
void afterElement(int x, node* after, node*& head, node*& tail)
Call afterElement(x, y, find(x, head), head, tail) to use this variant. Note you don't need to say (*find)(x, head).
There are more problems with your code than this compilation error. For example
node* N;
...
N->data = x;
is incorrect. You have not initialised N, it doesn't point anywhere, so you cannot use -> on it.
Another problem is that your program never modifies head, so the list doesn't have a chance to contain anything. This perhaps should be fixed by adding more functions (maybe something like beforeElement).
回答2:
I observe that you want to pass the "find" function as an argument to afterElement function.
Sure you can pass a function as an argument to other function. A function also gets stored in a memory location. This memory location is stored in the variable named same as the function name (in this case "find").
Now you are receiving the find function argument as a pointer in the afterElement function, so it is expecting an address, but you are passing the whole function. That's the reason why it is giving a compilation error. The correct code looks like :
#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;
}
}
}
I have checked with compilation, but check once for the results you are expecting. Thanks.
来源:https://stackoverflow.com/questions/55355715/how-do-i-solve-overloaded-function-with-no-contextual-type-information-error