I'm writing a program that provides the tools to create and manipulate a linked list. I've already finished the methods to add, delete nodes, etc. However, in order to create the method that orders the list, my teacher has asked me to make it with a function that receives another function as a parameter. I think the logic I used works well, however, it doesn't seem to work when calling the method from main. Here's the method:
...
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;
}
}
}
}
...
Edit: Updated the compiler to C++ 20. These are the new errors:
====================[ 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.
This is the whole code:
#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;
}
I must clarify that the teacher told me to use "auto" data type for the function passed as a parameter in the order metod. I've tried using pointers, but nothing seems to work. Thanks in advance!
Lista<string>::comparador
is not a function, it is a non-static member function. Those are very different things.
Your Lista<string>::ordenar
member function expects a function that accepts two string
s, but Lista<string>::comparador
isn't that. It accepts two strings
and a Lista<string>
object. The two types are simply incompatible.
The simplest way to fix that problem is to either make comparador
static
or move it out of your Lista
class template and make it a freestanding function.