我正在编写一个程序,它提供了创建和操作链接列表的工具。我已经完成了添加、删除节点等的方法。但是,为了创建对列表进行排序的方法,我的老师要求我使用一个接收另一个函数作为参数的函数来创建它。我认为我使用的逻辑工作得很好,但是,当从 main 调用该方法时,它似乎不起作用。方法如下:
...
int comparador(T valor1, T valor2){
if(valor1>valor2){
return 1;
}
else if(valor1<valor2){
return 0;
}
else{
return -1;
}
}
void ordenar(auto comparador(T,T)){
if(this->tam <= 1){
return;
}
for(Nodo<T>* i = this->cabeza ; i != NULL; i = i->siguiente){
for(Nodo<T>* j = i->siguiente; j != NULL; j = j->siguiente){
if(comparador(i->valor, j->valor)==1){
T temporal = i->valor;
i->valor = j->valor;
j->valor = temporal;
}
}
}
}
...
编辑:将编译器更新到 C++ 20。这些是新错误:
====================[ Build | untitled34 | Debug ]==============================
"C:\Program Files\JetBrains\CLion 2023.2.1\bin\cmake\win\x64\bin\cmake.exe" --build C:\Users\juanf\CLionProjects\untitled34\cmake-build-debug --target untitled34 -j 10
[1/2] Building CXX object CMakeFiles/untitled34.dir/main.cpp.obj
FAILED: CMakeFiles/untitled34.dir/main.cpp.obj
C:\PROGRA~1\JETBRA~1\CLION2~1.1\bin\mingw\bin\G__~1.EXE -g -std=gnu++20 -fdiagnostics-color=always -MD -MT CMakeFiles/untitled34.dir/main.cpp.obj -MF CMakeFiles\untitled34.dir\main.cpp.obj.d -o CMakeFiles/untitled34.dir/main.cpp.obj -c C:/Users/juanf/CLionProjects/untitled34/main.cpp
C:/Users/juanf/CLionProjects/untitled34/main.cpp: In function 'int main()':
C:/Users/juanf/CLionProjects/untitled34/main.cpp:131:21: error: no matching function for call to 'Lista<std::__cxx11::basic_string<char> >::ordenar(<unresolved overloaded function type>)'
131 | mi_lista.ordenar(mi_lista.comparador);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
C:/Users/juanf/CLionProjects/untitled34/main.cpp:100:10: note: candidate: 'template<class auto:16> void Lista<T>::ordenar(auto:16 (*)(T, T)) [with T = std::__cxx11::basic_string<char>]'
100 | void ordenar(auto comparador(T,T)){
| ^~~~~~~
C:/Users/juanf/CLionProjects/untitled34/main.cpp:100:10: note: template argument deduction/substitution failed:
C:/Users/juanf/CLionProjects/untitled34/main.cpp:131:21: note: mismatched types 'auto:16 (*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>)' and 'int (Lista<std::__cxx11::basic_string<char> >::*)(std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>)'
131 | mi_lista.ordenar(mi_lista.comparador);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
C:/Users/juanf/CLionProjects/untitled34/main.cpp:131:21: note: couldn't deduce template parameter 'auto:16'
ninja: build stopped: subcommand failed.
这是整个代码:
#include <iostream>
using namespace std;
template<typename T>
struct Nodo{
T valor;
Nodo<T>* siguiente;
Nodo(T valor){
this->valor = valor;
this->siguiente = NULL;
}
};
template<typename T>
struct Lista{
Nodo<T>* cabeza;
Nodo<T>* cola;
int tam;
Lista(){
this->cabeza = NULL;
this->cola = NULL;
this->tam = 0;
}
bool esta_vacia(){
return this->cabeza == NULL && this->cola == NULL;
}
void agregar_nodo(T valor){
Nodo<T>* nuevo_nodo = new Nodo<T>(valor);
if(this->esta_vacia()){
this->cabeza = nuevo_nodo;
this->cola = nuevo_nodo;
}else{
this->cola->siguiente = nuevo_nodo;
this->cola = nuevo_nodo;
}
this->tam= tam++;
}
void imprimir_lista(){
cout << "Valores de la lista:" <<endl;
for(Nodo<T>* itr = this->cabeza ; itr != NULL; itr = itr->siguiente){
cout << itr->valor << endl;
}
}
void insertarEnPos(int pos, T valor){
Nodo<T>* nuevo_nodo = new Nodo<T>(valor);
if(pos == 0){
nuevo_nodo->siguiente = this->cabeza;
this->cabeza = nuevo_nodo;
}
else if(pos == this->tam-1){
this->cola->siguiente = nuevo_nodo;
this->cola = nuevo_nodo;
}else{
Nodo<T>* itr = this->cabeza;
for(int cnt=0 ; cnt < pos-1; itr = itr->siguiente,cnt++){}
nuevo_nodo->siguiente = itr->siguiente;
itr->siguiente = nuevo_nodo;
}
this->tam= tam++;
}
void actualizarPos(int pos, T nuevoValor){
Nodo<T>* itr = this->cabeza;
for(int cnt=0; cnt<pos; itr = itr->siguiente, cnt++){
if(cnt==pos-1){
itr->siguiente->valor=nuevoValor;
}
}
}
void eliminarElemento(int pos){
Nodo<T>* itr = this->cabeza;
for(int cnt=0; cnt<pos || (cnt==0&&pos==0); itr = itr->siguiente, cnt++){
if(cnt==pos-1){
itr->siguiente=itr->siguiente->siguiente;
}
if(cnt==0&&pos==0){
this->cabeza=itr->siguiente;
}
}
}
int comparador(T valor1, T valor2){
if(valor1>valor2){
return 1;
}
else if(valor1<valor2){
return 0;
}
else{
return -1;
}
}
void ordenar(auto comparador(T,T)){
if(this->tam <= 1){
return;
}
for(Nodo<T>* i = this->cabeza ; i != NULL; i = i->siguiente){
for(Nodo<T>* j = i->siguiente; j != NULL; j = j->siguiente){
if(comparador(i->valor, j->valor)==1){
T temporal = i->valor;
i->valor = j->valor;
j->valor = temporal;
}
}
}
}
};
int main()
{
Lista<string> mi_lista;
mi_lista.agregar_nodo("1 asd asd");
mi_lista.agregar_nodo("2");
mi_lista.agregar_nodo("10");
mi_lista.agregar_nodo("-568");
mi_lista.insertarEnPos(2,"lk");
mi_lista.actualizarPos(2, "miau");
mi_lista.imprimir_lista();
cout<<"========================\nCon nodo eliminado:\n===================\n";
mi_lista.eliminarElemento(4);
mi_lista.imprimir_lista();
cout<<"========================\nOrdenando:\n===================\n";
mi_lista.ordenar(mi_lista.comparador);
return 0;
}
我必须澄清,老师告诉我在 order 方法中作为参数传递的函数使用“auto”数据类型。我尝试过使用指针,但似乎没有任何作用。 预先感谢!
Lista<string>::comparador
不是一个函数,它是一个非静态成员函数。这些是非常不同的事情。
您的
Lista<string>::ordenar
成员函数需要一个接受两个 string
的函数,但 Lista<string>::comparador
不是这样。它接受两个 strings
和一个 Lista<string>
对象。这两种类型根本不兼容。
解决该问题的最简单方法是制作
comparador
static
或将其移出 Lista
类模板并使其成为独立函数。