Home > Blockchain >  Forward declared friend template class don't need to include header file
Forward declared friend template class don't need to include header file

Time:05-04

Let us have an abstract template class Stack which will inherit realisation from second class parameter in template.

// file Stack.h
template <class T, template<typename> class Implementation>
class Stack : private Implementation<T>
{
public:
    Stack() {}
    virtual ~Stack() {}
    void push(const T& x) { Implementation<T>::push(x); }
    void pop() { Implementation<T>::pop(); }
    const T& top() { return Implementation<T>::top(); }
    bool empty() const { return Implementation<T>::empty(); }
};

Then, we have a class that will provide implementation and then be used in instantiating a template.

// file ListStack.h
template <class Elem>
class ListStack
{
private:
    size_t _size;
    struct ListNode
    {
        Elem _elem;
        ListNode * _next;
    };
    ListNode * _top;

    ~ListStack();
    friend class Stack<Elem, ListStack>;
public:
    ListStack();
    
    bool empty() const;
    const Elem& top() const;
    void pop();
    void push(const Elem & value);
    size_t size() const;
};

I declared destructor private and made Stack class a friend class so it can be only used when instantiating Stack class.

// file main.cpp
#include "Stack.h"
#include "ListStack.h"

int main()
{
    // ListStack<int> list; cannot instaniate
    Stack<int, ListStack> s;
}

The question is why ListStack.h don't need to include Stack.h file?

CodePudding user response:

In order for template code to be compiled, it needs to be called somewhere. In your case, you have two header files both defining what a template should be. The call to the template is being made in a file that includes both Stack and ListStack. Since you are creating the Stack variable in main.cpp, you can get away with List and ListStack not knowing each other in the header files.

I suspect that the Stack class will be defined in your main.cpp by the compiler but I'm not sure if I'm right about it.

As for the ListStack class instantiation error, that's because your destructor is private. Check this LINK for more details.

EDIT: You also need to create definitions for your ListStack class. Without that, nothing will work. I assumed for simplicity that you have empty definitions everywhere.

  • Related