如何在泛型类之外实现返回嵌入式类型的成员函数?

时间:2018-12-05 21:18:00

标签: c++ templates

我正在尝试模拟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'.

2 个答案:

答案 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>::iteratormember 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 { }; }; iteratorclass的事实,因此您必须struct作为define,这就是{{1} }发挥作用。通过允许编译器提示typetypename而不是ambiguity,编译器可以解析iterator。因此,它将迫使编译器使用此代码:

type

代替此:

member

Here是另一个template<typename T> class vec { public: struct iterator { }; }; ,可能会产生类似的编译器错误。