#trying to create doubly linked list using templates but encountring errors

27 messages · Page 1 of 1 (latest)

paper elbow
#

Errors :
||=== Build: Debug in ***(compiler: GNU GCC Compiler) ===|
main.cpp||In function 'int main()':|
error: 'template<class T> class DList' used without template parameters|
error: expected primary-expression before 'int'|
main.cpp|13|error: 'L' was not declared in this scope|
Code:
#ifndef DLish_h
#define DList_h
using namespace std;

// Define a template class DList for a doubly linked list
template < typename T >
class DList
{
public:
// Define a struct for the nodes in the list
struct Node
{
T data;
Node *next;
Node *prev;
};

// Create a type alias for Node pointers
typedef Node *Nodeptr;

// Constructor for initializing the list
DList ();

// Destructor for cleaning up memory
~DList ();

// Copy constructor to create a copy of another list
DList (const DList & other);

// Check if the list is empty
bool empty () const;

// Get the data in the first node
T headElement () const;

// Get the data in the last node
T tailElement () const;

// Get the data at a specific index
T getAt (int idx);

// Add a new node at the beginning of the list
void addHead (const T & newdata);

// Delete the first node
void delHead ();

// Add a new node at the end of the list
void addTail (const T & newdata);

// Delete the last node
void delTail ();

// Add a new node at a specific index
void addAt (int idx, const T & newdata);

// Delete the node at a specific index
void delAt (int idx);

// Get the length of the list
int length () const;

// Print the elements of the list
void print () const;

// Clear the entire list
void Clear ();

private:
// Helper function to create a dummy head node
void createDummyHead ();

// Helper function to navigate to a specific index
Nodeptr goToIndex (int idx);

// Pointer to the dummy head node
Nodeptr head;
};

#endif
#include <iostream>
using namespace std;

#include "dlist.h"

int main ()
{
DList::DList<int> L;//error...
L.print();

spare salmonBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

peak rapids
#

This formatting is unreadable. Put it on godbolt.org and send a link.

paper elbow
peak rapids
#

This is not too much better, but it seems like you put the implementation of your template into a separate cpp file. You can't do that. Put the implementation in the header or rename the file to .impl and #include it in the header.

#

I don't know why godbolt fails to compile the files properly.

#

Also DList::DList<int> L ; needs to be DList<int> L ; instead.

paper elbow
peak rapids
#

The .impl way and #includeing it is the best you can do.

#

Separating normally into .h and .cpp is not possible.

paper elbow
#

I'm new to programming so I don't know much but chatgpt is saying that it is possible to separate .h and .cpp files

peak rapids
#

For non-templates yes, for templates no.

paper elbow
#

Any reason???

peak rapids
#

Also don't listen to ChatGPT. It says things that sound plausible, not things that are correct.

#

The reason is that cpp files are compiled separately.

#

And templates are instantiated on use.

#

So you have a

template <class T>
void f(T t);

in a header and a .cpp that does

f(42);

which instantiates f<int>.
And then you have a .cpp with

template <class T>
void f(T t) {
  std::cout << t;
}

The problem here is that nobody has the definition for f<int>. The first .cpp only makes the declaration and doesn't know about the definition. The second .cpp only knows about the template, but it doesn't know that it has to instantiate f<int>.

#

So you end up with an undefined reference to f<int>.

#

Putting the definition into the header fixes it because then the user of f(42); provides the definition.

#

#includeing the file with the definition has the same effect, making the definition available to the caller.

#

There is an alternative, you can manually tell your .cpp file (the one that has the definition) to instantiate f<int>.

#

Apparenty template void f<int>(int); is the syntax for that, but you have to repeat that for every type you use which is not practical.

#

See https://stackoverflow.com/questions/495021 for further information. The title question is technically wrong because you can totally implement templates outside of a header file if you ensure the instantiator still has the definition, but the point still stands.

paper elbow
#

Thanks 🙂

spare salmonBOT
#

@paper elbow Has your question been resolved? If so, type !solved :)

paper elbow
#

!solved