Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't `std::forward_list::insert_after` return the first element inserted as other sequence containers?

Tags:

c++

Why doesn't std::forward_list::insert_after return the first inserted element as other sequence containers such as list and vector. Are there any deliberate reasons?

like image 817
Zhe Chen Avatar asked Dec 01 '15 15:12

Zhe Chen


3 Answers

forward_list is very different from other sequences, as is insert_after. In order to return the first inserted item it would have to use extra time and space to save off that element, while the last element will be available as part of the insertion algorithm. Not only that, but returning an iterator to the first element inserted from a range would give you an iterator you could use to insert into the middle of the range you just added, while an iterator to the end of the range lets you append additional data.

like image 184
Mark B Avatar answered Nov 19 '22 06:11

Mark B


After considering for some time, here is my understanding.

1. Normal sequence containers

For normal sequence containers, insert gets an iterator (which I'll call itl) as parameter, and inserts elements before itl. Then returns the iterator (itf) that points to the first inserted element. Now you have 2 iterators separately denoting the range (first and off-the-end) of the inserted elements.

elem-elem-inserted-inserted-inserted-elem-elem
             |                        |
           (itf)                    (itl)

However, insert operation may invalidate itl, so we need to consider the following two situations:

1.1 Linked structure

For linked structure, itl remains valid. Therefore (itf,itl) forms a valid range for inserted elements.

1.2 Contiguous structure

For contiguous structure, itl are invalidated after insertion. However such structures usually support random access, so it's still relatively easy to get an itl through simple arithmetic on itf. On the other hand, returning an iterator to the first inserted element preserves consistency.

2. Forward-list

insert_after for forward-list gets an iterator (itf) as parameter, and inserts elements after it. Then it returns an iterator to the last inserted element (itl). Because itf remains valid, we have a similar range again.

elem-elem-inserted-inserted-inserted-elem-elem
      |                        |
    (itf)                    (itl)

3. Conclusion

No matter whether insert operation returns a iterator to the first inserted element or to the last inserted element, it always tries to provide access to the beginning and end of inserted elements at the same time, which provides maximum flexibility.

like image 1
Zhe Chen Avatar answered Nov 19 '22 05:11

Zhe Chen


I don't know the committee's reasoning, but here's mine:

You can insert multiple elements, e.g. a "range". See http://en.cppreference.com/w/cpp/container/forward_list/insert_after

Returning the first element wouldn't be really valuable, as getting to the first element is trivial - you already have an iterator after which it was inserted.

OTOH, getting to the last inserted element might be costly, if you've inserted a lot of nodes.

like image 1
Karoly Horvath Avatar answered Nov 19 '22 06:11

Karoly Horvath