2015-06-24 4 views
1

Я реализую односвязный список. Вот класс узловОшибка объявления класса класса

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; 
}; 

Реализация отлично работает, если я объявляю элементы в узле общедоступными. Однако в тот момент, когда я объявляю их приватными и создаю класс класса друзей, я получаю следующую ошибку.

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». Благодарю.

+1

Ваш код не соответствует вашей ошибке. В вашей ошибке говорится 'friend class slist;'. В вашем коде говорится, что 'friend class slist ;'. Что он? –

+0

@TC Вы хотите, чтобы я создал класс вызывающего клиента. Поскольку ошибка возникает во время компиляции, которая включает в себя основную программу, создающую экземпляр списка и добавление нескольких членов. – Jumper

+2

Что вам нужно сделать, это предоставить SMALL, но COMPLETE образец кода, который иллюстрирует вашу проблему. В частности, неясно, какой порядок оба шаблона отображаются в исходном файле, если они отображаются в разных и т. Д. В любом случае, посмотрите на http://stackoverflow.com/questions/8967521/c-class-template-with -template-class-friend-whats-really-going-on-here – Peter

ответ

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

0

Друга объявление класса нужно это собственное объявление параметра шаблона без затенения параметров шаблона классов ограждающих:

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

template <typename T> 
class node{ 

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

Это делает 'slist ' другом 'node '. –

+0

Я пробовал это, но теперь я получаю следующую ошибку ../ node.hpp: 4: 35: ошибка: явная специализация неклассического класса «slist» template friend class slist ; ^ ~~~ – Jumper

+0

@Jumper Вы указали переадресацию для 'template class slist;'? –

Смежные вопросы