【发布时间】:2014-08-23 16:40:25
【问题描述】:
我开发了一个 c++ 树模板类,我想为其编写一组自定义迭代器。
GenericTree 类迭代器应按如下方式使用:
GenericTree<int> tree;
GenericTree<int>::iterator<PREORDER> preorder_iterator;
for(preorder_iterator = tree.begin(); preorder_iterator != tree.end(); ++preorder_iterato){
//Do something on the node pointed by the preorder_iterator.
}
在上面的例子中,++preorder_iterator 应该为 int 和 FORWARD 类型定义的迭代器类调用重载的 operator++() 方法,但是代码不能编译。我正在使用 g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
这是迭代器类的代码。为了缩短示例,我将 GenericTree 类替换为向量,并且完全省略了 begin() 方法源代码。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename P> class GenericTree{
public:
vector<P> data;
GenericTree() {}
~GenericTree(){}
class PREORDER{
};
class POSTORDER{
};
// ----------------------------------------------------------------------------------
template<typename IT> class my_iterator : public std::iterator<std::forward_iterator_tag, P> {
private:
int index;
protected:
public:
my_iterator() { index=0; }
~my_iterator() {}
IT& operator++();
};
// ----------------------------------------------------------------------------------
template<> my_iterator<PREORDER>& my_iterator<PREORDER>::operator++(){
cout << "Preorder visit of GenericTree of nodes containing int values." << endl;
return (*this);
}
template<> my_iterator<POSTORDER>& my_iterator<POSTORDER>::operator++(){
cout << "Postorder visit of GenericTree of nodes containing int values." << endl;
return (*this);
}
};
int main(int argc, char** argv){
GenericTree<int> c_int;
GenericTree<int>::my_iterator<GenericTree<int>::PREORDER> iterator_int;
for(iterator_int = c_int.begin(); iterator_int != c_int.end(); ++iterator_int)
;
GenericTree<string> c_string;
GenericTree<string>::my_iterator<GenericTree<string>::POSTORDER> iterator_str;
for(iterator_str = c_string.begin(); iterator_str != c_string.end(); ++iterator__str)
;
}
虽然是部分代码,但之前的代码返回的编译错误与我在构建完整源代码时遇到的编译错误相同:
g++ prova.cpp -o prova
prova.cpp:35:11: error: explicit specialization in non-namespace scope ‘class GenericTree<P>’
template<> my_iterator<PREORDER>& my_iterator<PREORDER>::operator++(){
^
prova.cpp:35:70: error: invalid use of incomplete type ‘class GenericTree<P>::my_iterator<GenericTree<P>::PREORDER>’
template<> my_iterator<PREORDER>& my_iterator<PREORDER>::operator++(){
^
prova.cpp:24:30: error: declaration of ‘class GenericTree<P>::my_iterator<GenericTree<P>::PREORDER>’
template<typename IT> class my_iterator : public std::iterator<std::forward_iterator_tag, P> {
^
prova.cpp:40:11: error: explicit specialization in non-namespace scope ‘class GenericTree<P>’
template<> my_iterator<POSTORDER>& my_iterator<POSTORDER>::operator++(){
^
prova.cpp:40:72: error: invalid use of incomplete type ‘class GenericTree<P>::my_iterator<GenericTree<P>::POSTORDER>’
template<> my_iterator<POSTORDER>& my_iterator<POSTORDER>::operator++(){
^
prova.cpp:24:30: error: declaration of ‘class GenericTree<P>::my_iterator<GenericTree<P>::POSTORDER>’
template<typename IT> class my_iterator : public std::iterator<std::forward_iterator_tag, P> {
^
prova.cpp: In function ‘int main(int, char**)’:
prova.cpp:51:27: error: ‘class GenericTree<int>’ has no member named ‘begin’
for(iterator_int = c_int.begin(); iterator_int != c_int.end(); ++iterator_int)
^
prova.cpp:51:58: error: ‘class GenericTree<int>’ has no member named ‘end’
for(iterator_int = c_int.begin(); iterator_int != c_int.end(); ++iterator_int)
^
prova.cpp:57:30: error: ‘class GenericTree<std::basic_string<char> >’ has no member named ‘begin’
for(iterator_str = c_string.begin(); iterator_str != c_string.end(); ++iterator__str)
^
prova.cpp:57:64: error: ‘class GenericTree<std::basic_string<char> >’ has no member named ‘end’
for(iterator_str = c_string.begin(); iterator_str != c_string.end(); ++iterator__str)
^
prova.cpp:57:73: error: ‘iterator__str’ was not declared in this scope
for(iterator_str = c_string.begin(); iterator_str != c_string.end(); ++iterator__str)
^
make: *** [prova] Error 1
我找不到为 PREORDER 和 POSTORDER 类型定义 operator++() 的两个模板特化的正确方法。
如果我使用 template<> 关键字,编译器会抱怨特化超出范围,我不明白为什么。
将两个模板特化移出 GenericTree 类主体并没有解决问题。
提前感谢您的帮助!
f.
【问题讨论】:
-
将
my_iterator类的声明/定义移到GenericTree<T>之外。 -
错误说明了它到底发生了什么,专业化不能在类范围内。
标签: c++ templates tree iterator