【问题标题】:How to implement a member function outside the generic class that returns an embedded type?如何在返回嵌入类型的泛型类之外实现成员函数?
【发布时间】:2018-12-05 21:18:00
【问题描述】:

我正在尝试模拟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;
};

现在我需要在vec类之外实现iterator begin();

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'.

【问题讨论】:

  • 要使用 C++,您需要是一个优秀的拼写者,并且始终使用“ierat”或“iterat”,但不能同时使用两者。对于 C++,拼写非常重要。
  • @SamVarshavchik:我没明白你的意思?
  • 这意味着您的原始问题在一个地方将班级拼写为ierat,在另一种情况下拼写为iterat。不幸的是,计算机还不够聪明,无法识别错别字并自行修复。这取决于碳基生命形式,以确保所有内容始终正确拼写。我想我短暂地看到了那个错字已更正,但由于一个冲突的问题编辑而被恢复。所以,要么当前版本的问题是正确的,要么你需要修正你的拼写;或者显示的代码不是有错误的真实代码,而是手动输入的假代码。想知道是哪种情况。
  • @SamVarshavchik:那是因为这个类有点大,所以我手动编写了它,其中包含一些拼写错误。但是没有,它被编辑了。
  • 最好把它拼写为“迭代器”——这是其他人都习惯看到的,他们会确切地知道你的意思:前向非常量迭代器。

标签: c++ templates


【解决方案1】:

你需要这样添加typename

template<class T>
typename vec<T>::iterator vec<T>::begin() { // typename here is necessary

    iteraror tmp;
    tmp.elem = elem;

    return tmp;
} 

【讨论】:

    【解决方案2】:

    您的编译器错误准确地解释了正在发生的事情:

    我收到警告:

    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&lt;T&gt;::iteratorvec&lt;T&gt;member variable 还是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 { 
        }; 
    };
    

    由于iteratorclassstruct,您必须将define 作为type,这就是typename 发挥作用的地方。这允许编译器通过向编译器提示iteratortype 而不是member 来解析ambiguity。因此它会强制编译器使用这个:

    template<typename T>
    class vec {
    public:
        struct iterator {
        };
    };
    

    而不是这个:

    template<typename T>
    class vec {
    public:
        T iterator;
    };
    

    Here 是另一个 Q/A,它会产生类似的编译器错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      相关资源
      最近更新 更多