How come a C++ template returns a hexadecimal value?

I have a simple C++ class that uses generic templates to store and retrieve generic variables. Storing them is no issue but returning the generic variable returns a hexadecimal value.

Could someone tell me why it’s doing that?

node.h

#pragma once
#include <iostream>

template <typename T>
class Node {
    private:
        T data;
        Node *next_node;

    public:
        Node(T data) {
            this->data = data;
            std::cout << "Node with data - " << this->data << " - has been created." << std::endl;
        }
        
        T get_data() {
            return this->data;
        }
        
        void set_next_node(Node next) {
            this->next_node = next;
        }

        Node get_next_node() {
            return this->next_node;
        }
};

main.cpp

#include <iostream>
#include "node.h"

int main() {

    Node node = new Node("Hello World");

    std::cout << "Node data: " << node.get_data() << std::endl;

    return 0;
}

output

gabriel@desktop:/media/gabriel/main/repositories/CPP Sandbox/nodes$ g++ main.cpp -o main
gabriel@desktop:/media/gabriel/main/repositories/CPP Sandbox/nodes$ ./main
Node with data - Hello World - has been created.
Node with data - 0x55ec552d3eb0 - has been created.
Node data: 0x55ec552d3eb0


>Solution :

The problem you are facing is that you are using new to create a node but then trying to assign the pointer returned to a non-pointer Node variable.

This line is the problem:

Node node = new Node("Hello World");

What this does is to first construct an unnamed Node object with a template type of const char *; then, by using the pointer to that new object to initialize your node variable, you are constructing a second Node object, with the deduced template type being Node*. The cout lines showing hexadecimal values are correctly displaying the address value stored in that second, named Node variable.

You can get round this in several ways. The easiest is to not use the new operator:

Node node{ "Hello World" }; // Construct object directly

Another way would be to continue using the new call but then make your node a pointer:

int main() 
{
    Node<const char*>* node = new Node("Hello World"); // Or auto node = new Node("Hello World");
    std::cout << "Node data: " << node->get_data() << std::endl; // Now we need "->" instead of the "."
    delete node;
    return 0;
}

The first line of code in your main function is, effectively, doing this:

Node node{ new Node("Hello World") };

Thus creating two nodes with the named one having it’s template type as Node<const char*>*. Or, to put it another way, your first line is equivalent to the following, with explicit template types:

Node< Node<const char*>* > node = new Node<const char*>("Hello World");

Also note that the = operator here is not an assignment but an initialization; this is why the constructor is called.

Leave a Reply