Отсутствуют аргументы шаблона - PullRequest
0 голосов
/ 27 сентября 2011

Это часть домашнего задания, но я по возможности уменьшил проблему.Представленный код на самом деле ничего не делает, просто создает некоторые объекты, так что я перешел к чисто языковым проблемам.

Я думаю, что мой вопрос: возможно ли для класса шаблона создать другой класс того же самогоТип шаблона?

Назначение должно иметь main.cc следующим образом:

#include "linkedlist.hh"

int main()
{
    LinkedList<int> aList;
    ListIterator elements = aList.iterator(); // if commented out, then no error
}

У меня есть следующие ссылки для linkslist.hh:

template <typename T> class LinkedList;
template <typename T> class ListIterator;

template <typename T>
    class LinkedList {
    public:
    ListIterator<T> iterator();
};

template <typename T>
    ListIterator<T> LinkedList<T>::iterator() {
    return new ListIterator<T>;
}

template <typename T>
    class ListIterator {
};

, которые даютследующая ошибка с g ++ - 4.6:

main.cc: In function ‘int main()’:
main.cc:6:18: error: missing template arguments before ‘elements’
main.cc:6:18: error: expected ‘;’ before ‘elements’

и аналогичная ошибка с clang ++ - 2.9:

main.cc:6:5: error: cannot refer to class template 'ListIterator' without a
      template argument list
    ListIterator elements = list.iterator();
    ^
In file included from main.cc:1:
./linkedlist.hh:16:11: note: template is declared here
    class ListIterator {

ОБНОВЛЕНИЕ: Да, если я смогу изменить main.cc, тогдаЯ мог бы сделать следующее, но я не думаю, что это то, что является назначением.

main.cc

#include "linkedlist.hh"

int main()
{
    LinkedList<int> aList;
    ListIterator<int> elements = aList.iterator();
}

и connectedlist.hh

template <typename T> class LinkedList;
template <typename T> class ListIterator;

template <typename T>
    class LinkedList {
    public:
    ListIterator<T> iterator();
};

template <typename T>
    ListIterator<T> LinkedList<T>::iterator() {
    ListIterator<T> anIterator;
    return anIterator;
}

template <typename T>
    class ListIterator {
};

Ответы [ 5 ]

1 голос
/ 27 сентября 2011

Разве это не должно быть ListIterator<int>?

0 голосов
/ 28 сентября 2011

Переименуйте ListIterator и добавьте typedef MyListIterator<int> ListIterator; в конец заголовка.Тогда основной код будет работать без изменений.

Это просто хитрость, чтобы этот конкретный код работал.Вы не можете сделать итератор, совместимый со стандартной библиотекой, который не является шаблоном или не зависит от шаблона.Если вам не нужно создавать итератор, совместимый со стандартной библиотекой, вы можете использовать метод, называемый стиранием типов (ответ Вона Катона), но это довольно сложная тема.

0 голосов
/ 27 сентября 2011

Для этого в C ++ 11 была добавлена ​​директива auto

см. Вывод типа

0 голосов
/ 27 сентября 2011

Так вы могли бы реализовать универсальный итератор, который мог бы выполнять некоторые базовые операции над итератором для списка элементов любого типа, но это было бы необычно.

struct ListIteratorBase {
  virtual void advance() = 0;
  virtual bool atEnd() const = 0;
  virtual ~ListIteratorBase() { }
};

template <typename T>
struct BasicListIterator : ListIteratorBase {
  virtual void advance(); // implement this
  virtual bool atEnd() const;  // and this
  T value() const; // and this
};

struct ListIterator {
  template <typename T> ListIterator(BasicListIterator<T> &iter)
  : iter_ptr(new BasicListIterator<T>(iter))
  {
  }

  ~ListIterator() { delete iter_ptr; }

  void operator++() { iter_ptr->advance(); }
  bool atEnd() const { return iter_ptr->atEnd(); }

  // Method to get the value for a particular type.  It is up to the caller to
  // make sure the type is right at runtime.
  template <typename T>
  T get<>() const
  {
    BasicListIterator<T> *p = dynamic_cast<BasicListIterator<T> *>(iter_ptr);
    assert(p);
    return p->value();
  }

  ~ListIterator() { delete iter_ptr; }

  ListIteratorBase *iter_ptr;
};

Тогда вам понадобится

template <typename T>
BasicListIterator<T> LinkedList<T>::iterator() { ... }
0 голосов
/ 27 сентября 2011

ListIterator - это шаблон, очевидно, вы должны задать ему параметр шаблона. Попробуйте ListIterator<int>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...