我正在尝试模拟class vector
及其iterator
,所以这就是问题所在:
template<class T>
class vec {
public:
vec();
vec(const int);
virtual ~vec();
T* getElem()const;
const int size()const;
void resize(const int);
void print()const;
T& operator[](int);
struct iterator {
T* elem;
iterator* operator++();
};
iterator begin();
iterator end();
private:
T* elem;
int sz;
};
现在我需要在类iterator begin();
之外实现vec
:
template<class T>
vec<T>::iterator vec<T>::begin() {
vec<T>::iterator tmp;
tmp.elem = elem;
return tmp;
}
我得到警告:
Severity Code Description Project File Line
Warning C4346 iterator': dependent name is not a type.
还有一个错误:
Severity Code Description Project File Line
Error C2061 syntax error: identifier 'iterator'.
答案 0 :(得分:6)
您需要通过以下方式添加typename
:
template<class T>
typename vec<T>::iterator vec<T>::begin() { // typename here is necessary
iteraror tmp;
tmp.elem = elem;
return tmp;
}
答案 1 :(得分:3)
您的编译器错误完全解释了正在发生的事情:
我得到警告:
Severity Code Description Project File Line Warning C4346 iterator': dependent name is not a type.
还有一个错误:
Severity Code Description Project File Line Error C2061 syntax error: identifier 'iterator'.
编译器不知道vec<T>::iterator
是member variable
的{{1}}还是vec<T>
。
我们必须使用nested type
来消除这种歧义,因为用户typename
已在其答案中显示。他们向您展示了如何解决编译器错误,在我解释了为什么会得到它的地方。
没有Raindrop7
的代码将生成模糊的代码!
类外的函数保持不变:
typename
这就是它产生歧义的原因:
您的意思是:
template<class T> vec<T>::iterator vec<T>::begin() { vec<T>::iterator tmp; tmp.elem = elem; return tmp; }
或
vec<t>::iterator as in template<typename T> class vec { public: T iterator; };
由于vec<t>::iterator as in
template<typename T>
class vec {
public:
struct iterator {
};
};
是iterator
或class
的事实,因此您必须struct
作为define
,这就是{{1} }发挥作用。通过允许编译器提示type
是typename
而不是ambiguity
,编译器可以解析iterator
。因此,它将迫使编译器使用此代码:
type
代替此:
member
Here是另一个template<typename T>
class vec {
public:
struct iterator {
};
};
,可能会产生类似的编译器错误。