1

I need to build a linked list with a template, but I have no idea why is not working, I've built linked lists before, but never with templates. Right now my problem is that, if I create the list everything is ok, but when I try to insert something to it, I get the following errors:

Error   C2664   'Nodo<D>::Nodo(Nodo<D> &&)': cannot convert argument 1 from 'const int' to 'const Nodo<D> &'    Datos2  d:\google drive\visual studio 2015\projects\datos2\datos2\listaSimple.h 69


Error   C2664   'Nodo<D>::Nodo(Nodo<D> &&)': cannot convert argument 1 from 'const int' to 'const Nodo<D> &'    Datos2  d:\google drive\visual studio 2015\projects\datos2\datos2\listaSimple.h 73

with my following code:

    //linkedList.h
#pragma once
#ifndef _LISTASIMPLE_H
#define _LISTASIMPLE_H

template<class D> 
struct Nodo
{
    int carga;
    int binario;

    D caracter;

    Nodo<D> *Siguiente;//means next
};



template<class D>
class listaSimple
{

public:
    listaSimple();
    ~listaSimple();

    void InsertarInicio(const D&);
    bool ListaVacia();
    void Mostrar();




private:
    Nodo<D> *primero;
    Nodo<D> *ultimo;

};

template<class D> 
listaSimple<D>::listaSimple()
{
    primero = NULL;
}

template<class D>
listaSimple<D>::~listaSimple()
{
    Nodo<D> *aux;
    while (primero != NULL)
    {
        aux = primero;
        primero = primero->Siguiente;
        delete aux;
    }
}

template<class D>
void listaSimple<D>::InsertarInicio(const D& dato)
{
    if (ListaVacia())
    {
        primero = new Nodo<D>(dato);
    }
    else
    {
        Nodo<D> *nodoNuevo = new Nodo<D>(dato);
        nodoNuevo->Siguiente = primero;
        primero = nodoNuevo;
    }
}

template<class D>
bool listaSimple<D>::ListaVacia()
{
    if (primero == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}

template<class D>
inline
void listaSimple<D>::Mostrar()
{
    Nodo<D> *aux = primero;
    while (aux != NULL)
    {
        cout << aux->caracter << "->";
        aux = aux->Siguiente;
    }
}

and

//Source.cpp
#include <iostream>
#include <string>
#include "linkedList.h"


using namespace std;

int main() {
    listaSimple<int> Nueva;
    Nueva.InsertarInicio(5);

    system("pause");
    return 0;
}
7
  • if (EmptyList) is that the actual code? Because you seem to want to call the function, in which case you are missing parentheses, e.g.: if (EmptyList()) Commented Nov 5, 2016 at 22:13
  • @UnholySheep yep, sorry, translation error. thanks for pointing it out Commented Nov 5, 2016 at 22:16
  • What is Siguiente? Also class D is not defined. listaSimple<int> NewList is all wrong, you probably mean linkedList<D> NewList where my D is some class which is not shown. Commented Nov 5, 2016 at 22:25
  • @BarmakShemirani I edited the errors, siguiente means next in spanish, and lista Simple means "simple list". Is there a difference in using "template<class D>" vs using "template<typename D>?" as far as I've read, is exactly the same Commented Nov 5, 2016 at 22:28
  • "I edited the errors". No you did not. There is still "Nodo". The errors you have posted do not match actual errors present in the code. Please post the exact code you have compiled, rather than some edited version thereof, and post the exact errors you are getting. Use copy and paste mechanism without any editing whatsoever. Commented Nov 5, 2016 at 22:34

1 Answer 1

1

See the corrected version of Node and linkedList. Note that Node and linkedList do not contain any information about the actual data. In fact you can declare the data (struct MyData) at the end.

For printing I added a function to:

node->data.print();

This way Node and linkedList are not directly responsible for printing the data, and they don't need to know anything about the data. They can ask DataType to print the data. DataType must contain a print function to print its own content.

template<typename DataType>
struct Node
{
    DataType data;
    Node<DataType> *Next;
    Node()
    {
        Next = nullptr;
    }
};

template<typename DataType>
class linkedList
{
public:
    linkedList()
    {
        first = NULL;
    }

    ~linkedList()
    {
        Node<DataType> *aux;
        while (first != NULL)
        {
            aux = first;
            first = first->Next;
            delete aux;
        }
    }

    void InsertBegining(const DataType& data)
    {
        Node<DataType> *newNode = new Node<DataType>;
        newNode->data = data;
        if (first)
        {
            newNode->Next = first;
            first = newNode;
        }

        first = newNode; //<== you forgot this
    }

    void Print()
    {
        Node<DataType> *walk = first;
        while (walk)
        {
            walk->data.print();
            walk = walk->Next;
        }
    }

private:
    Node<DataType> *first;
};

Now you can declare MyData and use it. Make sure MyData includes a print function. Also MyData has to be POD (plain old data, it can't contain pointers) because of the way data is being assigned.

int main() 
{
    struct MyData
    {
        int charge;
        int binario;
        char ch;
        void print()
        {
            cout << charge << ", " << binario << ", " << ch << "\n";
        }
    };

    linkedList<MyData> list;
    MyData data;

    data.binario = 1;
    data.ch = 'A';
    data.charge = 10;
    list.InsertBegining(data);

    data.binario = 2;
    data.ch = 'B';
    data.charge = 20;
    list.InsertBegining(data);

    list.Print();

    system("pause");
    return 0;
}

Another method:

You can add << operator overload for MyData

struct MyData
{
    int charge;
    int binario;
    char ch;

    friend std::ostream& operator<< (std::ostream &out, MyData &x)
    {
        out << x.ch << ", " << x.binario << ", " << x.charge;
        return out;
    }
};

So MyData knows how to print itself. Example:

MyData data;
data.ch = 'A';
data.binario = 1;
data.charge = 10;
cout << data << "\n";

This should print "A, 1, 10".

Then you can change the linkList::Print() to

...
void Print()
{
    Node<DataType> *walk = first;
    while (walk)
    {
        std::cout << walk->data << "\n";
        walk = walk->Next;
    }
}

Now linkedList is independent of MyData as long as MyData has << operator overload (and its data is POD). You can also use this linked list for fundamental types. Example:

linkedList<int> test;
test.InsertBegining(1);
test.InsertBegining(2);
test.Print();
Sign up to request clarification or add additional context in comments.

4 Comments

that's great! But I still have some questions, do I have to declare a <myData> struct every time I want to use the template?
That's a very basic question, think about how it works and try declaration in different places to see what works. You can declare MyData in global scope and use it everywhere.
I thought of that, but since templates are giving me such a headache I though I should ask first. In any case, thanks for helping me out, I think I'm getting the hang of it now
By the way you can also overload << operator for MyData, see updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.