这是家庭作业的一部分,但我尽可能地减少了问题。提供的代码并没有真正做任何事情,只是创建一些对象,所以我归结为纯语言问题。
我认为我的问题是:模板类是否可以创建具有相同模板类型的另一个类?
分配是使用main.cc:
#include "linkedlist.hh"
int main()
{
LinkedList<int> aList;
ListIterator elements = aList.iterator(); // if commented out, then no error
}
我对linkedlist.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
#include "linkedlist.hh"
int main()
{
LinkedList<int> aList;
ListIterator<int> elements = aList.iterator();
}
和linkedlist.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 {
};
答案 0 :(得分:1)
不应该是ListIterator<int>
?
答案 1 :(得分:0)
ListIterator
是一个模板,显然你必须给它一个模板参数。试试ListIterator<int>
答案 2 :(得分:0)
这就是你如何实现一个泛型迭代器,它可以在迭代器上对任何类型的元素列表进行一些基本操作,但这很不寻常。
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() { ... }
答案 3 :(得分:0)
为此,在C ++ 11中,添加了 auto 指令
答案 4 :(得分:0)
重命名ListIterator并将typedef MyListIterator<int> ListIterator;
添加到标题的末尾。然后主代码将不加修改地工作。
这只是使这个特定代码工作的一个技巧。您不能使符合标准库的迭代器不依赖于模板或模板。如果您不必创建符合标准库的迭代器,那么您可以使用一种称为类型擦除的技术(Vaughn Cato的答案),但这是一个相当高级的主题。