0

I'm trying to understand how including works in C++. I have two questions about it. The first one is on how properly import the .h file. For example I created the following HashNode.h file:

namespace HashNode{
    template<class Data>
    class HashNode{
    private:
        Data data;
        HashNode *next;

    public:
        explicit HashNode(const Data &data);

        Data getKey();

        ~Node();
    };
}

So in the HashNode.cpp file, it should like:

#include "HashNode.h"

using namespace HashNode;

template <class Data> // ~~~ HERE 1 ~~~
HashNode::HashNode(const Data &data) {//todo};

template <class Data> // ~~~ HERE 2 ~~~
Data* HashNode::getKey() {
    //todo
}

HashNode::~Node() {
    //todo
}

This way it works but do I have to include template <class Data> beside each function which uses Data? Why it does not recognize Data without including template <class Data>?

Also I have created the Hash.h file which should use the HashNode.h file:

#include "HashNode.h"
using namespace HashNode;

namespace Hash {
    template <class Data>
    class Hash {
        typedef enum {
            GOOD = 0,
            BAD = -1,
            BAD_ALLOC = -2
        } Status;

    private:
        HashNode **hash;
        int capacity;
        int size;

    public:
        explicit Hash(int size);

        Status insertData(const Data &data);

        ~Hash();
    };
}

But I get the the following error: Can't resolve type 'HashNode'. Why it can't see the import? In the Hash.cpp file I get Unused import statement for #include "HashNode.h". Why is that? Also, what if I want to include private functions - should them be in the .h file or in the .cpp file?

vesii
  • 2,760
  • 4
  • 25
  • 71
  • 1
    Why `namespace HashNode` around your `class HashNode`? That doesn't serve any purpose. – Paul Evans Jun 14 '19 at 12:30
  • 1
    I'm not sure whether it is a good idea to name a `namespace` and a `class` in that `namespace` with the same identifier. Together with `using namespace`, this becomes very confusing - for me and as it appears for the compiler as well. – Scheff's Cat Jun 14 '19 at 12:30
  • 3
    You should implement your templates in your headers. https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – drescherjm Jun 14 '19 at 12:30
  • Importing is fundamentally different from including. – L. F. Jun 14 '19 at 12:32
  • `template // ~~~ HERE 1 ~~~ HashNode::HashNode(const Data &data) {//todo};` is actually defining a new template function in namespace HashNode and is not defining the HashNode method. For that you want `template HashNode::HashNode(const Data &data) {//todo};` – ChrisW Jun 14 '19 at 12:38
  • `#include "HashNode.h"` literally just means 'include the contents of the file "HashNode.h" here'. – molbdnilo Jun 14 '19 at 12:40
  • "Unused import statement" is not a message that a C++ compiler would produce. I suspect that it comes from your IDE. Don't rely on your IDE's "live" error messages. – molbdnilo Jun 14 '19 at 12:41
  • 1
    C++ doesn't have anything called "import". `#include` manipulates text files. It is completely oblivious to classes, namespaces, templates, or pretty much anything else you might find in a C++ source file. – n. m. could be an AI Jun 14 '19 at 12:47

1 Answers1

0

The member functions of a template class are themselves also templates. Because of this, they need to be defined with any required template parameters and template type definitions.

About your second question, it has to do with namespaces. As I see it, having namespace and class under the same naming might cause you ambiguity. Although, everything seems to be fine on the structural side of the code. Try using #pragma once or some kind of guards to prevent this kind of issues.

Stf Kolev
  • 640
  • 1
  • 8
  • 21