2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 [Borland C++ 3.1] Непонятки с шаблоном
Сообщение28.11.2010, 19:58 
Вот мой код:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
/* mylist.h */
template <class T>
class TList {
private:
  struct TNode {
    T *data;
    TNode *prev, *next;
  } *fFirst, *fLast;
  TNode *find(T *);
public:
  TList();
  ~TList();
  void addAfter(T *, T *after);
  T *remove(T *);
  void clear();
  T *prev(T *);
  T *next(T *);
  T *first();
  T *last();
};

/* mylist.cpp */
#include <stddef.h>
#include "mylist.h"
template <class T>
TList<T>::TList() {
  fFirst = fLast = NULL;
}
template <class T>
TList<T>::~TList() {
  clear();
}
template <class T>
TList<T>::TNode *TList<T>::find(T *e) {
  TNode *n = fFirst;
  while (n) {
    if (n->data == e) return n;
    n = n->next;
  }
  return NULL;
}
template <class T>
void TList<T>::addAfter(T *e, T *after) {
  if (!e) return;
  if (!after) {
    TNode *n = new TNode;
    n->data = e;
    n->prev = NULL;
    n->next = fFirst;
    if (fFirst) fFirst->prev = n;
    else fLast = n;
    fFirst = n;
  } else {
    TNode *n = new TNode, *aftern = find(after);
    if (!aftern) return;
    n->data = e;
    n->prev = aftern;
    n->next = aftern->next;
    aftern->next->prev = n;
    aftern->next = n;
    if (aftern == fLast) fLast = n;
  }
}
template <class T>
T *TList<T>::remove(T *e) {
  TNode *n = find(e);
  if (!n) return NULL;
  if (n == fFirst) {
    fFirst = n->next;
    fFirst->prev = NULL;
  } else if (n == fLast) {
    fLast = n->prev;
    fLast->next = NULL;
  } else {
    n->prev->next = n->next;
    n->next->prev = n->prev;
  }
  delete n;
  return e;
}
template <class T>
void TList<T>::clear() {
  TNode *n = fFirst;
  while (n) {
    delete n->data;
    TNode *tmp = n;
    n = n->next;
    delete tmp;
  }
  fFirst = fLast = NULL;
}
template <class T>
T *TList<T>::prev(T *e) {
  TNode *n = find(e);
  if (!n || !(n->prev)) return NULL;
  return n->prev->data;
}
template <class T>
T *TList<T>::next(T *e) {
  TNode *n = find(e);
  if (!n || !(n->next)) return NULL;
  return n->next->data;
}
template <class T>
T *TList<T>::first() {
  return fFirst->data;
}
template <class T>
T *TList<T>::last() {
  return fLast->data;
}

Declaration syntax error вот в какой строке:
TList<T>::TNode *TList<T>::find(T *e) { // и т. д.
(курсор на букве T, т. е. фактически между ней и звёздочкой)

Ничего не понимаю.

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение28.11.2010, 21:26 
Добавьте typename:
Используется синтаксис C++
template <class T>
typename TList<T>::TNode *TList<T>::find(T *e) {
  typename TNode *n = fFirst;
  while (n) {
    if (n->data == e) return n;
    n = n->next;
  }
  return NULL;
}
 

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение28.11.2010, 21:41 
BC написан раньше принятия стандарта и typename не включает.

Отделил TNode отдельным шаблоном, необходимое переписал, и теперь две аналогичные ошибки (nеперь в заголовочном файле) вот где:
template <class T>

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение28.11.2010, 23:09 
2arseniiv
Самым простым решением (для первоначальной задачки) будет определение проблемных функций прямо в объявлении их класса (inline).

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 14:40 
Всё равно Declaration syntax error. Как в последнем случае. :?

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 15:53 
arseniiv
А если вообще избавиться от *.cpp-файла и перенести реализации всех функций в *.h-файл, разместив их сразу после объявления класса?

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 16:12 
Тогда ошибка ещё и в том месте определения шаблона для реализации конструктора.

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 16:36 
Я (кажется) понял. У Вас в первоначальном варианте декларация структуры TNode находится в разделе private и снаружи этот тип "не виден".

Хотя... Все равно выдается похожая ошибка... Странно.

По поводу измененного варианта (вынесение TNode в виде отдельного шаблона). Вот такой код у меня компилируется:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#ifndef MYLIST_H

#define MYLIST_H

#include <stddef.h>

template <class T>
struct TNode {
  T *data;
  TNode *prev, *next;
};

template <class T>
class TList {
private:
  TNode<T> *fFirst, *fLast;
  TNode<T> *find(T *);
public:
  TList();
  ~TList();
  void addAfter(T *, T *after);
  T *remove(T *);
  void clear();
  T *prev(T *);
  T *next(T *);
  T *first();
  T *last();
};

template <class T>
TList<T>::TList() {
  fFirst = fLast = NULL;
}
template <class T>
TList<T>::~TList() {
  clear();
}
template <class T>
TNode<T> *TList<T>::find(T *e) {
  TNode<T> *n = fFirst;
  while (n) {
    if (n->data == e) return n;
    n = n->next;
  }
  return NULL;
}
template <class T>
void TList<T>::addAfter(T *e, T *after) {
  if (!e) return;
  if (!after) {
    TNode<T> *n = new TNode<T>;
    n->data = e;
    n->prev = NULL;
    n->next = fFirst;
    if (fFirst) fFirst->prev = n;
    else fLast = n;
    fFirst = n;
  } else {
    TNode<T> *n = new TNode<T>, *aftern = find(after);
    if (!aftern) return;
    n->data = e;
    n->prev = aftern;
    n->next = aftern->next;
    aftern->next->prev = n;
    aftern->next = n;
    if (aftern == fLast) fLast = n;
  }
}
template <class T>
T *TList<T>::remove(T *e) {
  TNode<T> *n = find(e);
  if (!n) return NULL;
  if (n == fFirst) {
    fFirst = n->next;
    fFirst->prev = NULL;
  } else if (n == fLast) {
    fLast = n->prev;
    fLast->next = NULL;
  } else {
    n->prev->next = n->next;
    n->next->prev = n->prev;
  }
  delete n;
  return e;
}
template <class T>
void TList<T>::clear() {
  TNode<T> *n = fFirst;
  while (n) {
    delete n->data;
    TNode<T> *tmp = n;
    n = n->next;
    delete tmp;
  }
  fFirst = fLast = NULL;
}
template <class T>
T *TList<T>::prev(T *e) {
  TNode<T> *n = find(e);
  if (!n || !(n->prev)) return NULL;
  return n->prev->data;
}
template <class T>
T *TList<T>::next(T *e) {
  TNode<T> *n = find(e);
  if (!n || !(n->next)) return NULL;
  return n->next->data;
}
template <class T>
T *TList<T>::first() {
  return fFirst->data;
}
template <class T>
T *TList<T>::last() {
  return fLast->data;
}

#endif

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 19:56 
А на чём вы компилировали? Ведь это только, наверно, с BC3.1 такая проблема.

Пока что я обратно восстановил всё к первоначальному виду, в котором использовался класс элемента.

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 20:14 
arseniiv
arseniiv в сообщении #381811 писал(а):
А на чём вы компилировали?
На VS 2008.
А у Вас мой вариант компилируется?

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 20:39 
Нет, у меня был в точности такой же в одно из времён.

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 20:45 
arseniiv
Не могли бы Вы все же попытаться скомпилировать именно тот код, который я привел? Ради чистоты эксперимента. Хотя, может быть, это у меня под вечер синдром Фомы разыгрался...

 
 
 
 Re: [Borland C++ 3.1] Непонятки с шаблоном
Сообщение29.11.2010, 21:08 
Я уверен, что там тот же код, что был когда-то некомпилирующимся с вероятностью 1. Всё же, идеальных компиляторов, наверно, не бывает.

 
 
 [ Сообщений: 13 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group