LINUX.ORG.RU

[C++] Наследование шаблонов


0

1

Есть класс List и его наследник SList, в List есть вложенный класс iterator.

// List.h
template <class T> class List {
    protected:
        ....

    public:
    	class iterator;
        List();

    	iterator end() {
    	    return iterator(_pEnd->next);
        }
        iterator begin() {
    	    return iterator(_pBegin);
        }
             
        class iterator {
            protected:
                ListNode<T> *pi;
            public:
                iterator() : pi(0) {}
                iterator(ListNode<T>* _pi) : pi(_pi) {}
                iterator(const iterator &it) : pi(it.pi) {}
                iterator operator++() {
                    pi = pi->next;
                    return *this;
                }
                T& operator*() {
                    return pi->value;
                }
                bool operator!=(const iterator &it) {
                    return it.pi != pi;
                }
                iterator& operator=(const iterator &rhs) {
                    pi = rhs.pi;
                    return *this;
                }
        };
};
// SList.h
template <class T> class SList : public List<T> {
    public:
        class iterator : public List<T>::iterator {};
        SList() : List<T>() {}
        SList(int size) : List<T>(size) {}
        SList(int size, T data) : List<T>(size, data) {}
    
        iterator insert(T data) {
            iterator it1, it2;
            for(it1 = begin(); it1 != end(); ++it1) { // вот тут ругается
                ...
            }
        }
};

в int main создаю объект SList и больше ничего. Компилятор при сборке ругается:

SList.h: In member function ‘SList<T>::iterator SList<T>::insert(T)’:
SList.h:27: error: there are no arguments to ‘begin’ that depend on a template parameter, so a declaration of ‘begin’ must be available
SList.h:27: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
SList.h:27: error: there are no arguments to ‘end’ that depend on a template parameter, so a declaration of ‘end’ must be available
make: *** [SList.o] Ошибка 1
Что не так?


Ответ на: комментарий от geekless

спасибо за ссылки! но либо я не понял, либо не то
если перед begin() и end() указать this->(или SList<T>), то получаю вот такую ругань

SList.h:27: error: no match for ‘operator=’ in ‘it1 = List<T>::begin() [with T = int]()’
SList.h:12: note: candidates are: SList<int>::iterator& SList<int>::iterator::operator=(const SList<int>::iterator&)
operator= же есть и для объектов List итератор работает.

surik ()
Ответ на: комментарий от surik

Суть в том, что в строке 27 нужен
operator=(const derived &)
а у тебя есть только
operator=(const base &)

Manhunt ★★★★★ ()
Ответ на: комментарий от Manhunt

получаю вот такое:

SList.h:27: error: ‘iterator’ does not name a type
SList.h:27: note: (perhaps ‘typename List<T>::iterator’ was intended)
а если написато вот так,
        iterator insert(T data) {
            typename List<T>::iterator it1;
            for(it1 = this->begin(); it1 != this->end(); ++it1) {
                cout << "sdfdsf" << endl;
            }
        }
то собирается без ошибок, т.е каждый раз теперь когда мне понадобится итератор в SList нужно писать typename List<T>::iterator ?

surik ()
Ответ на: комментарий от surik

> тогда опять ругается на operator= :(

Попробовал у себя, нет никакой ругани.

$cat c.cc

template <class T> class ListNode {
    public:                        
        ListNode *next;            
};                                 


template <class T> class List {
    protected:                 
//        ....                 
       ListNode<T>* _pEnd, _pBegin;

    public:
       class iterator;
        List();

       iterator end() {
           return iterator(_pEnd->next);
        }
        iterator begin() {
           return iterator(_pBegin);
        }

        class iterator {
            protected:
                ListNode<T> *pi;
            public:
                iterator() : pi(0) {}
                iterator(ListNode<T>* _pi) : pi(_pi) {}
                iterator(const iterator &it) : pi(it.pi) {}
                iterator operator++() {
                    pi = pi->next;
                    return *this;
                }
                T& operator*() {
                    return pi->value;
                }
                bool operator!=(const iterator &it) {
                    return it.pi != pi;
                }
                iterator& operator=(const iterator &rhs) {
                    pi = rhs.pi;
                    return *this;
                }
        };
};

template <class T> class SList : public List<T> {
    public:
//        class iterator : public List<T>::iterator {};
        typedef typename List<T>::iterator iterator;
        SList() : List<T>() {}
        SList(int size) : List<T>(size) {}
        SList(int size, T data) : List<T>(size, data) {}

        iterator insert(T data) {
            iterator it1, it2;
            for(it1 = this->begin(); it1 != this->end(); ++it1) { // вот тут ругается
//                ...
            }
        }
};

$ g++ -c c.cc

$ g++ --version

g++ (SUSE Linux) 4.4.1 [gcc-4_4-branch revision 150839]
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Manhunt ★★★★★ ()
Ответ на: комментарий от Manhunt

[code=cpp] ListNode<T>* _pEnd, _pBegin; [/code]

вот из за этого я за рисовани звездочек рядом с именем переменной, а не рядом с именем типа

[code=cpp] ListNode<T> *_pEnd, *_pBegin; [/code]

код автора распарсить анрил, тем более какой то выдранный из контекста кусок

vvviperrr ★★★★★ ()
Ответ на: комментарий от vvviperrr

> вот из за этого я за рисовани звездочек рядом с именем переменной

Черт, что-то сегодня ляп на ляпе..

Manhunt ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.