Why do we need a list argument in the splice func cpp? Why only iterators aren't sufficient?
Result is the same if I pass l1
or l2
as a second argument
l1.splice(st, l1, it, it2);
or l1.splice(st, l2, it, it2);
prints 1 4 5 2 3
#include <bits/stdc++.h>
using namespace std;
int main()
{
// initializing lists and iterator
list<int> l1 = { 1, 2, 3 };
list<int> l2 = { 4, 5 };
auto it = l2.begin();
auto it2 = l2.end();
auto st = l1.begin();
std::advance(st,1);
// result the same if in splice l1 or l2
// 1 4 5 2 3
l1.splice(st, l2, it, it2);
cout << "list l1 after splice operation" << endl;
for (auto x : l1)
cout << x << " ";
return 0;
}
This call
l1.splice(st, l1, it, it2);
invokes undefined behavior.
When you need to extract a range of elements then other data members of the list as for example size
must be updated.
If you will execute for example this statement
std::cout << l2.size() << '\n';
you can get unexpected result.
Here is a demonstrative program compiled with gcc 8.3.
#include <iostream>
#include <list>
#include <iterator>
int main()
{
std::list<int> lst1 = { 1, 3, 5, 7, 9 };
std::list<int> lst2 = { 0, 2, 4, 6, 8 };
lst1.splice( std::next( std::begin( lst1 ) ),
lst1,
std::begin( lst2 ),
std::end( lst2 ) );
for ( const auto &item : lst1 )
{
std::cout << item << ' ';
}
std::cout << '\n';
for ( const auto &item : lst2 )
{
std::cout << item << ' ';
}
std::cout << '\n';
std::cout << "the size of lst2 is " << lst2.size() << '\n';
return 0;
}
Its output is
1 0 2 4 6 8 3 5 7 9
the size of lst2 is 5
If you will change lst1
to lst2
in this call
lst1.splice( std::next( std::begin( lst1 ) ),
lst2, // <===
std::begin( lst2 ),
std::end( lst2 ) );
then you will the correct output
1 0 2 4 6 8 3 5 7 9
the size of lst2 is 0
^^^