0

I have a template class LinkedList, which depends on the template type T. Inside of the class LinkedList, there's a nested class Node, which also depends T. I try to implement Node class in a seperate .h/.cc files, but failed somehow.

The LinkedList.h is:

template <typename T>
class LinkedList {
public:
    class Node;

private:
    std::shared_ptr<Node> head;
    std::shared_ptr<Node> tail;
};

BaseNode.h is:

template<typename kOwner>
class BaseNode {
    // some definition
}

Node.h is:

template <typename T>
class LinkedList<T>::Node : public BaseNode<LinkedList<T>>{
private:
    T data;
    std::shared_ptr<Node> next;
    void Start();
}

Node.cc is:

template<typename T>
void LinkedList<T>::Node(MetadataManager *metadata_manager) :
    BaseNode(metadata_manager){}

template<typename T>
void ListedList<T>::Node::Start() {
    // do some operations
}

The error I got is

error: member initializer 'BaseNode' does not name a non-static data member or base class
        BaseNode(metadata_manager) {

Can someone tell me how to implement it please?

Tinyden
  • 524
  • 4
  • 13
  • 1
    "failed somehow"? Can you be more precise please? What goes wrong? And you should always define templates in header files. – cigien Jul 23 '20 at 18:13
  • What error are you getting? – Geno C Jul 23 '20 at 18:14
  • `void typename` -- no, take out `typename`. What's after it isn't a type, it's a member function. And even then, the template definition is only visible in `Node.cc`. It should go in `Node.h`. – cdhowie Jul 23 '20 at 18:20
  • 1
    Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Richard Critten Jul 23 '20 at 18:20
  • I'm working with the legacy code with my teammate, one of my responsibility is to templatize the current classes, i'm afraid I have no choice but to implement the nested class in .h/.cc file seperately. – Tinyden Jul 23 '20 at 18:34
  • @Dentiny You can't unless you explicitly instantiate every version of the template that will ever be used. – cdhowie Jul 23 '20 at 18:38
  • Yes, since there's only two versions, I actually did explicit instantiation – Tinyden Jul 23 '20 at 18:39
  • 1
    @Dentiny Okay then the compile-time error is likely due to that `typename` after `void` which shouldn't be there. What follows isn't a type. – cdhowie Jul 23 '20 at 18:39
  • After I remove the typename keyword, another error occurs: member initializer 'BaseNode' does not name a non-static data member or base class Here, I'm trying to call the ctor of the templated BaseNode – Tinyden Jul 23 '20 at 18:41
  • My advice if you get compiler errors always post the exact text of the error messages in the question so we don't have to play a game of guess what the errors are. It also makes for a better question for future readers. – drescherjm Jul 23 '20 at 18:42
  • And what line of code does that occur on? – cdhowie Jul 23 '20 at 18:43
  • node.cc:6:2: error: member initializer 'BaseNode' does not name a non-static data member or base class BaseNode(metadata_manager) { – Tinyden Jul 23 '20 at 18:43
  • `#include "node.h" template LinkedList::Node::Node( MetadataManagerInterface *metadata_manager) : BaseNode(metadata_manager) { }` – Tinyden Jul 23 '20 at 18:44
  • btw, how could you use the code block format on the comment/ – Tinyden Jul 23 '20 at 18:45
  • Use ` before and after the code with no spaces between ` and the code – drescherjm Jul 23 '20 at 18:47
  • You may just want to edit the question with additional information – drescherjm Jul 23 '20 at 18:48
  • You don't inherit from `BaseNode`, you inherit from `BaseNode>`. Change the initializer list appropriately: `: BaseNode>(metadata_manager) { }` – cdhowie Jul 23 '20 at 18:48
  • You might be confused about that because you can omit the template arguments within a template type itself, but `BaseNode` _isn't_ the type you're defining here. However, in this context `LinkedList` is the same thing as `LinkedList` since you _are_ in the context of that type, so you _could_ simplify both the inheritance and the initializer list to `BaseNode`, but you still have to give the arguments to `BaseNode`. This is because you could inherit from `BaseNode` and `BaseNode`, for example. They are not the same type, so just `BaseNode` would be ambiguous. – cdhowie Jul 23 '20 at 18:52
  • 1
    One thing that strikes me, `Node.h` really should have `#include "BaseNode.h"` because that's a direct dependency. You should not rely on other source files having to (precariously) have already included the direct dependencies for you code. If this isn't the case, it'd be nice if the code provided was a complete [mcve], it would take a lot of the guesswork out of trying to help. – Eljay Jul 23 '20 at 18:57
  • Yes, i have to say I'm quite confused about the template stuff...And there's link error after object file compilation, Jeus... – Tinyden Jul 23 '20 at 19:00
  • `void ListedList::Node::Start()` isn't declared anywhere; probably supposed to be `LinkedList` and not `ListedList`. – Eljay Jul 23 '20 at 19:06
  • Ah that's my typo – Tinyden Jul 23 '20 at 19:08
  • 1
    I recommend that you test the code provided to see that it actually reproduces the problem you've encountered. If the code doesn't reproduce the problem, then it is leading everyone down the primrose path. – Eljay Jul 23 '20 at 19:34

0 Answers0