I have made a template class for a node in a linked list and I’m trying to have it output its contents to an output stream by overloading <<. However my current code:
#include <iostream>
using namespace std;
template<class NType> class Node;
template<class NType>
class Node {
private:
void deletePointer(NType* p);
public:
NType data;
Node *prev, *next;
template<typename T>
struct is_pointer { static const bool value = false; };
template<typename T>
struct is_pointer<T*> { static const bool value = true; };
Node();
Node(NType data);
~Node();
};
int main() {
Node<int> *n1 = new Node<int>();
Node<int> *n2 = new Node<int>(10);
std::cout << "Node 1: " << n1 << std::endl;
std::cout << "Node 2: " << n2 << std::endl;
}
template<class NType> inline std::ostream & operator << (std::ostream& out, const Node<NType> &node){
out << node.data;
return out;
}
template<class NType> inline Node<NType>::Node()
:data(NULL), prev(NULL), next(NULL)
{
}
template<class NType> inline Node<NType>::Node(NType data)
:data(data), prev(NULL), next(NULL)
{
}
template<class NType> inline Node<NType>::~Node(){
if(is_pointer<NType>::value){
deletePointer(&data);
} else {
return;
}
}
template<class NType> inline void Node<NType>::deletePointer(NType* p){
delete p;
}
Outputs memory locations rather than the data within the nodes. This happens with primitive types such as int and the like as if it didn’t know what kind of data was in the NType container.
Node 1: 0x741010
Node 2: 0x741030
Node 3: 0x741070
Node 4: 0x741090
I’ve tried using typename rather than class but still no dice… Is there any way to dynamically find out what type the template is using and cast or something prior to insertion? I know I can make a ton of redundant code for all the primitives but that seems wasteful and unnecessary.
If it helps any, I’m compiling on Arch Linux x64 with GCC v4.6.2 20111223
Edit: Since a lot of people are mentioning it. I’ve also tried putting the class outside as a friend and as a stand alone function neither of which work because the stream outputs address rather than the data itself regardless of where I put it. There are no private data values to be accessed so it’s OK for it to not be a friend.
Edit:
Test case: http://ideone.com/a99u5
Also updated source above.
Edit:
Added the remaining portion of my code to assist Aaron in his understanding of the code.
Your code declares the
operator<<as a member function, so it would actually take thethispointer as first argument andostreamas second. Instead it needs to be a free function:however if your
operator<<needs access to private data you need to declare it as a friend function instead:Now for your output: If your
operator<<was invoked the compiler would know the type ofNTypeand do the right thing when streaming thedatamember. However since youroperator<<should not have worked (as written) and it seems to give you memoryaddresses as output I would assume you have something like the following:Now just for curiosity sake: Why are you implementing what looks curiously like a linked list yourself instead of simply using
std::list?Edit:
Now that we can see the testcase it seems the assumptions about how the
operator<<was called was correct. The output needs to be changed to:to actually invoke the
operator<<forNode, instead of the generic one forT*