Как реализовать функцию-член вне универсального класса, который возвращает встроенный тип? - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь смоделировать 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 голосов
/ 06 декабря 2018

Ваши ошибки компилятора точно объясняют, что происходит:

И я получаю предупреждение:

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 из 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 как type, и именно здесь typename входит виграть.Это позволяет компилятору разрешить ambiguity, давая компилятору подсказку, что iterator является type, а не member.Таким образом, это заставит компилятор использовать это:

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

вместо этого:

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

Здесь - это еще один Q/A, который мог бы произвести аналогичноеошибка компилятора.

0 голосов
/ 06 декабря 2018

Вам нужно добавить typename таким образом:

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

    iteraror tmp;
    tmp.elem = elem;

    return tmp;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...