Search code examples
c++templatesfriend

How to make a templated class a friend of another templated class


For educational purposes I'm writing a templated Stack class based on a singly linked list. I have written a class for a node:

template <typename T>
class StackNode {
    private:
        T data;
        StackNode<T> *next;
        // TODO: make Stack a friend
};

and I started writing the stack itself:

template <typename T>
class Stack {
    private:
        StackNode<T> *head;
        unsigned long long int size;
    public:
        Stack(): head(nullptr), size(0) {}
        void push(const T& element) {
            StackNode<T> *new_element = new StackNode<T>;
            new_element -> data = element;
            new_element -> next = head;
            head = new_element;
            ++size;
        }
};

Obviously, these two lines

            new_element -> data = element;
            new_element -> next = head;

are giving me trouble, because I'm trying to get access to private members. I want to make Stack a friend of StackNode. How can I do that?

When I write friend class Stack<T> in my TODO line in the StackNode, my CLion IDE underlines Stack with a red squiggly line and it says that I have redefinition of Stack as a different kind of symbol. I don't know how to fix that.

UPD: my main function looks like this:

int main() {
    Stack<long long int> s;
    s.push(12);
    return 0;
}

I appreciate any help.


Solution

  • Well, your issue is still not reproducible / complete. If you want to such an issue to be solved, try an online compiler like wandbox. An example is complete, if you can copy paste it into an online compiler and it leads to the error, that you want to be solved.

    We can only guess what your issue is. Maybe you missed the forward decl. This way a friend declaration is done with the same class dependency structure as in your example:

    #include <iostream>
    
    template<class T>
    class Foo;
    
    template<class T>
    class Bar
    {
    public:
        Bar(T t) : v(t) {}
    
    private:
        T v;
        friend class Foo<T>;
    };
    
    template<class T>
    class Foo
    {
    public:
        void Fun(Bar<T> bar)
        {
            std::cout << bar.v;
        }
    };
    
    int main()
    {
        Bar<int> bar(99);
        Foo<int> foo;
        foo.Fun(bar);
    }