我有一个类正在使用列表来实现它:
template<class T>
class Ring {
list<T> lst;
..
我希望使用模板参数选择underliyng实现(数据结构),它应该默认为list
。我认为应该这样做:
template<class T,class Y = list<T>>
class Ring {
Y lst;
..
其中T
是数据结构的泛型类型,Y
是容器的类型。但它没有编译,问题出在哪里?
编辑:这是完整的代码。现在我看到问题在于使用迭代器而不是模板。
#include <iostream>
#include <list>
#include <string>
using namespace std;
template<class T,class Y = list<T>>
class Ring{
Y lst;
public:
// Declaration necessary so the following
// 'friend' statement sees this 'iterator'
// instead of std::iterator:
class iterator;
friend class iterator;
class iterator : public std::iterator<
std::bidirectional_iterator_tag, T, ptrdiff_t> {
Y::iterator it;
Y* r;
public:
// "typename" necessary to resolve nesting:
iterator(Y& lst,
const typename Y::iterator& i)
: r(&lst), it(i) {}
bool operator==(const iterator& x) const {
return it == x.it;
}
bool operator!=(const iterator& x) const {
return !(*this == x);
}
Y::reference operator*() const {
return *it;
}
iterator& operator++() {
++it;
if (it == r->end())
it = r->begin();
return *this;
}
iterator operator++(int) {
iterator tmp = *this;
++*this;
return tmp;
}
iterator& operator--() {
if (it == r->begin())
it = r->end();
--it;
return *this;
}
iterator operator--(int) {
iterator tmp = *this;
--*this;
return tmp;
}
iterator insert(const T& x) {
return iterator(*r, r->insert(it, x));
}
iterator erase() {
return iterator(*r, r->erase(it));
}
};
void push_back(const T& x) {
lst.push_back(x);
}
iterator begin() {
return iterator(lst, lst.begin());
}
int size() { return lst.size(); }
};
int main() {
Ring<string> rs;
rs.push_back("one");
rs.push_back("two");
rs.push_back("three");
rs.push_back("four");
rs.push_back("five");
Ring<string>::iterator it = rs.begin();
it++; it++;
it.insert("six");
it = rs.begin();
// Twice around the ring:
for (int i = 0; i < rs.size() * 2; i++)
cout << *it++ << endl;
} ///:~
错误:
Severity Code Description Project File Line Suppression State
Error C2061 syntax error: identifier 'iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 16
Error C2238 unexpected token(s) preceding ';' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 16
Error C2061 syntax error: identifier 'reference' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 29
Error C2079 'it' uses undefined class 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 77
Error C2334 unexpected token(s) preceding '{'; skipping apparent function body STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 29
Error C2027 use of undefined type 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 77
Error C2228 left of '.insert' must have class/struct/union STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 79
Error C2027 use of undefined type 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 80
Error C2100 illegal indirection STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 83
Error C2088 '<<': illegal for class STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 83
答案 0 :(得分:0)
问题与默认模板参数无关 - 该位是正确的。
此代码无法编译的原因是Y::iterator
是依赖类型,即它取决于模板参数Y
。这意味着您需要说
typename Y::iterator it;
在您的iterator
内部成员列表中,
typename Y::reference operator*() const { ... }
在iterator::operator*()
声明中。
有关为何需要此详细说明,请参阅this question。