朋友类声明错误

时间:2015-06-24 22:55:38

标签: c++

我正在实施一个单链表。这是节点类

template <typename T> class node{

    friend class slist<T>;
    public:
        explicit node():data(0), next(NULL){}

    private:
        T data;
        node<T> *next;

};

这是列表类。

template<typename T> class slist{
    public:
        slist():head(NULL){}


        bool empty(){
            return head == NULL;
        }

        void add_front(const T& data){
            if(head == NULL){
                node<T>* n = new node<T>();
                n->data = data;
                n->next = NULL;
                head = n;
                return;
            }
            node<T>* n = new node<T>();
            n->data = data;
            n->next = head;
            head = n;
        }

        void remove_front(){
            if(head == NULL) return;
            node<T>* old = head;
            head = old->next;
            delete old;
        }

        void print_list(){
            if(head == NULL) return;
            while(!empty()){
                std::cout<<head->data<<std::endl;
                head = head->next;
            }
        }

        ~slist(){

            while(!empty()) remove_front();

        }

    private:
        node<T>* head;
};

如果我将节点中的成员声明为public,则实现完全正常。然而,当我将它们声明为私有并将slist作为朋友类时,我得到以下错误。

In file included from src.cpp:3:
./slist.hpp:5:28: error: redefinition of 'slist' as different kind of symbol
template<typename T> class slist{
                           ^
./node.hpp:4:15: note: previous definition is here
        friend class slist;

我显然可以找到单链表的其他实现,但我试图了解这里出了什么问题。所以请不要主动提出建议,因为“google it”。感谢。

2 个答案:

答案 0 :(得分:2)

您需要将List类声明为模板类:

#include <iostream>

template<typename T> class List; //<< fwd decl

template<typename T> class Node {
    int i;
public:
    friend class List<T>; //<< usage same as you have now
    Node() : i(123) {}
    int value() { return i; }
};

template<typename T> class List { //<< definition
public:
    List(Node<T>* node) { node->i++; }
};

int main() {
    Node<int> node{};
    List<int> list{&node};
    std::cout << node.value() << "\n";
}

http://ideone.com/2RUWgj

答案 1 :(得分:0)

友元类声明需要它自己的模板参数声明,而不会遮蔽封闭类模板参数:

template<typename U> class slist; // Forward declare slist

template <typename T> 
class node{

    template<typename U> // <<<<<
    friend class slist<U>;
                    // ^ <<<<<
    // ...
};