3

I know that std::forward_list is a single linked list. I'm wondering how to move the first element(head) to the end of the forward_list. No copies or creating new nodes!

I've tried the following:

std::forward_list<int> l2 = {10,11,12};
auto beginIt = l2.begin();
beginIt = std::next(beginIt);
l2.splice_after(l2.end(),l2,l2.begin(),beginIt); 

for(int n : l2)
    std::cout << n << ' ';
std::cout << '\n';

But it doesn't work. Is there a way to do that?

TigerTV.ru
  • 1,058
  • 2
  • 16
  • 34
  • Possible duplicate of [std::forward\_list and std::forward\_list::push\_back](https://stackoverflow.com/questions/8742462/stdforward-list-and-stdforward-listpush-back) – Ken Y-N Dec 10 '18 at 03:48
  • @KenY-N, here is no push_back function. – TigerTV.ru Dec 10 '18 at 03:49
  • But it's the same requirement, finding the last element in the list as `l2.end()` is one after the end. – Ken Y-N Dec 10 '18 at 03:51
  • @KenY-N: In this case used the same forward_list, without creation a node. – TigerTV.ru Dec 10 '18 at 03:54
  • 1
    The linked question is a piece of the answer to this one, because to do the move correctly you need an iterator to the last element. But a proper answer to this one should explain why, and what to do with it. – aschepler Dec 10 '18 at 03:55

2 Answers2

3

For your purposes, splice_after needs an iterator to the last element. That is, the element right before end(). There's no cheap way to get this:

auto pos = l2.begin();
while(std::next(pos) != l2.end()) ++pos;

Then, splice_after for a single element asks for an iterator pointing before that element. For the first element, that is before_begin():

l2.splice_after(pos, l2, l2.before_begin()); 
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • If we use `auto before_end=l2.begin();` before `splice_after` we get iterator on the last element. So it can be used next time without while-loop. This behaviour I wanted to get. Thanks. – TigerTV.ru Dec 10 '18 at 06:45
1

You could use rotate:

std::rotate(l.begin(), std::next(l.begin()), l.end());
chenzhongpu
  • 6,193
  • 8
  • 41
  • 79