Search code examples
c++friend-functionclass-template

Errors with friend function in Clion c++


I have written a small code to practice data structures and the beautiful C++.

The code below works completely fine if make the variables in SNode to public and remove the friend class ... line. However, based on the textbook I'm reading, this should be working fine.

The errors I get are as follow:

  • line 11: error: ‘SLinkedList’ is not a class template
  • In instantiation of ‘class SNode’: line 10: error: template argument required for ‘class SLinkedList’
  • In instantiation of ‘void SLinkedList::addFront(const E&) [with E = int]’: line 9: error: ‘int SNode<int>::elem’ is private

Below is the code written in Clion:

#include <iostream>

using namespace std;

template <typename E>
class SNode {
private:
    E elem; //line 9
    SNode<E> * next; // line 10
    friend class SLinkedList<E>; //Provide SLinkedList access to these private variables (line 11)
};



template <typename E>
class SLinkedList {
public:
    SLinkedList();
    ~SLinkedList();
    bool empty() const;
    const E& front() const;
    void addFront(const E& e);
    void removeFront();
    void printAll() const;
private:
    SNode<E> * head;
};



template <typename E>
SLinkedList<E>::SLinkedList():head(NULL){};

template <typename E>
bool SLinkedList<E>::empty() const {
    return (head==NULL);
}


template <typename E>
void SLinkedList<E>::addFront(const E &e) {
    SNode<E> * node = new SNode<E>;
    node->elem=e;
    node->next=head;
    head=node;
}

template <typename E>
void SLinkedList<E>::removeFront() {
    SNode<E> * temp = head;
    head = head->next;
    delete temp;
}


template <typename E>
const E& SLinkedList<E>::front() const {
    return head->elem;
}

template <typename E>
SLinkedList<E>::~SLinkedList() {
    while (!empty()){
        removeFront();
    }
}

template <typename  E>
void SLinkedList<E>::printAll() const {
    SNode<E> * itr =head;
    while (itr != NULL){
        cout<<itr->elem<<"  ";
        itr = itr->next;
    }
}




int main() {
    cout << "Hello, World!" << endl;
    SLinkedList<int> test ;
    test.addFront(2);
    test.addFront(3);
    test.addFront(6);
    test.addFront(8);
    test.addFront(19);
    test.printAll();



    return 0;
}

Solution

  • friend class SLinkedList<E>;
    

    This template is not declared yet. Your C++ code gets compiled in an orderly manner, from the beginning of your source file to the end. Until this template gets declared later on in this header file, the compiler has no clue what this is.

    The solution is very simple: add a forward declaration to the beginning of the header file, because the SNode template declaration:

    template <typename E> class SLinkedList;
    
    template <typename E>
    class SNode {
    private:
        E elem;
        SNode<E> * next;
        friend class SLinkedList<E>;
    };