开发者

C++: calling member functions within constructor?

The following code raises a runtime error:

#include <iostream>
#include <iterator>
#include <ext/slist>

class IntList :  public __gnu_cxx::slist<int> {
public:
    IntList() { tail_ = begin(); } // seems that there is a problem here
    void append(const int node) { tail_ = insert_after(tail_, node); }

private:
    iterator tail_;
};

int 开发者_开发技巧main() {
    IntList list;

    list.append(1);
    list.append(2);
    list.append(3);

    for (IntList::iterator i = list.begin(); i != list.end(); ++i) {
        std::cout << *i << " ";
    }

    return 0;
}

Seems that the problem is in the constructor IntList(). Is it because it calls the member function begin()?


Looks like You are inserting after end();

In the body of the constructor

IntList() { tail_ = begin(); }

the base class is constructed and it's members can be called, but for an empty list, it should return end();


The documentation for slist<> indicates that the iterator provided to insert_after must be dereferenceable.

Since your list is empty the begin() returns end() and is thus not dereferenceable.

See documentation here:

http://www.sgi.com/tech/stl/Slist.html

iterator insert_after(iterator pos, const value_type& x)

pos must be a dereferenceable iterator in *this. (That is, pos may not be end().) Inserts a copy of x immediately following pos. The return value is an iterator that points to the new element. Complexity: constant time.


Your problem is not in the constructor but in the first call to append(). Because your list is empty begin() equals end(). end() is a valid iterator, but the one after that isn't. To solve that particular problem try calling insert() instead.

That said, a fast peek at <ext/slist> confirms that the destructor of slist isn't virtual, which means slist wasn't intended to be derived from.


.begin() is invalid if there are no elements in your collection.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜