C++ Reference: Standard C++ Library reference: Containers: list: list: splice

夏侯腾
2023-12-01

C++官网参考链接:https://cplusplus.com/reference/list/list/splice/

公有成员函数 
<list>
std::list::splice
C++98
entire list (1)    
void splice (iterator position, list& x);
single element (2)    
void splice (iterator position, list& x, iterator i);
element range (3)    
void splice (iterator position, list& x, iterator first, iterator last);
C++11
entire list (1)    
void splice (const_iterator position, list& x);
void splice (const_iterator position, list&& x);
single element (2)    
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);
element range (3)    
void splice (const_iterator position, list& x, const_iterator first, const_iterator last);
void splice (const_iterator position, list&& x, const_iterator first, const_iterator last);
在list之间转移元素
将元素从x转移到容器中,并将它们插入到position。
这将有效地将这些元素插入到容器中,并从x中删除它们,从而改变两个容器的大小。该行动不涉及构造或析构任何元素。不管x是左值还是右值,或者value_type是否支持移动构造,它们都被转移。
第一个版本(1)将x的所有元素传输到容器中。
第二个版本(2)只将i所指向的元素从x转移到容器中。
第三个版本(3)将范围[first,last)从x转移到容器中。

形参 
position 
在容器中插入x元素的位置。
成员类型iterator和const_iterator是指向元素的双向iterator(bidirectional iterator )类型。
x
相同类型的list对象(即具有相同的模板形参T和Alloc)。
如果position指向一个实际上没有被拼接的元素,则该形参可能为*this(对于第一个版本,这种情况永远不会发生,但对于其他版本,这种情况是可能的)。

指向x中的一个元素的iterator。只有这个元素被转移。
Iterator是一个成员类型,定义为双向iterator类型。
成员类型iterator和const_iterator是指向元素的双向iterator(bidirectional iterator)类型。
first,last
在x中指定元素范围的iterator。将范围[first,last)中的元素转移到position。
注意,该范围包括first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。
成员类型iterator和const_iterator是指向元素的双向iterator(bidirectional iterator)类型。

返回值
没有返回值。

用例
// splicing lists
#include <iostream>
#include <list>

int main ()
{
  std::list<int> mylist1, mylist2;
  std::list<int>::iterator it;

  // set some initial values:
  for (int i=1; i<=4; ++i)
     mylist1.push_back(i);      // mylist1: 1 2 3 4

  for (int i=1; i<=3; ++i)
     mylist2.push_back(i*10);   // mylist2: 10 20 30

  it = mylist1.begin();
  ++it;                         // points to 2

  mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" still points to 2 (the 5th element)
                                          
  mylist2.splice (mylist2.begin(),mylist1, it);
                                // mylist1: 1 10 20 30 3 4
                                // mylist2: 2
                                // "it" is now invalid.
  it = mylist1.begin();
  std::advance(it,3);           // "it" points now to 30

  mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
                                // mylist1: 30 3 4 1 10 20

  std::cout << "mylist1 contains:";
  for (it=mylist1.begin(); it!=mylist1.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "mylist2 contains:";
  for (it=mylist2.begin(); it!=mylist2.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
输出: 
mylist1 contains: 30 3 4 1 10 20
mylist2 contains: 2

复杂度
对于(1)和(2)是常量。
最多达到在(3)中转移的元素数量中的线性。

iterator的有效性
在调用之前,不修改与容器相关的iterator、指针和reference。
指向被转移元素的iterator、指针和reference会一直指向那些相同的元素,但iterator现在会迭代到元素被转移到的容器中。

数据竞争
容器和x都被修改了。
同时访问或修改它们的元素是安全的,但是迭代x或包含position的范围就不安全了。

异常安全
如果两个容器中的allocator不相等,如果指定的任何的iterator或范围无效,或如果x在(1)中为*this,或如果position在(3)中为[first,last)范围内,则会导致未定义行为。
否则,该函数永远不会抛出异常(无抛出保证)。 

 类似资料: