List 是一个双向的链表,相比较其他容器,list在插入,删除,移动元素时比较好。
1 List 的构造函数:
list( );
explicit list(
const Allocator& _Al
);
explicit list(
size_type _Count
);
list(
size_type _Count,
const Type& _Val
);
list(
size_type _Count,
const Type& _Val,
const Allocator& _Al
);
list(
const list& _Right
);
template
list(
InputIterator _First,
InputIterator _Last
);
template
list(
InputIterator _First,
InputIterator _Last,
const Allocator& _Al
);
list(
list&& _Right
);
2 List的成员变量
value_type |
Thefirst template parameter (T) |
|
allocator_type |
Thesecond template parameter (Alloc) |
defaults to:allocator |
reference |
allocator_type::reference |
forthe default allocator:value_type& |
const_reference |
allocator_type::const_reference |
forthe default allocator: constvalue_type& |
pointer |
allocator_type::pointer |
forthe default allocator:value_type* |
const_pointer |
allocator_type::const_pointer |
forthe default allocator: const value_type* |
iterator |
a bidirectionaliterator to value_type |
convertible to const_iterator |
const_iterator |
a bidirectionaliterator to const value_type |
|
reverse_iterator |
reverse_iterator |
|
const_reverse_iterator |
reverse_iterator |
|
difference_type |
asigned integral type, identical to:iterator_traits::difference_type |
usually the same as ptrdiff_t |
size_type |
anunsigned integral type that can represent any non-negative valueof difference_type |
usually the same as size_t |
对应变量的用法:
(1):reference,const_reference
reference back( );
const_reference back( ) const;
include
#include
int main( )
{
using namespace std;
list c1;
c1.push_back( 10 );
c1.push_back( 11 );
int& i = c1.back( );
const int& ii = c1.front( );
cout << "The last integer of c1 is " << i << endl;
i--;
cout << "The next-to-last integer of c1 is " << ii << endl;
}
(2):difference_type
#include
#include
#include
int main( )
{
using namespace std;
list c1;
list ::iterator c1_Iter, c2_Iter;
c1.push_back( 30 );
c1.push_back( 20 );
c1.push_back( 30 );
c1.push_back( 10 );
c1.push_back( 30 );
c1.push_back( 20 );
c1_Iter = c1.begin( );
c2_Iter = c1.end( );
list ::difference_type df_typ1, df_typ2, df_typ3;
df_typ1 = count( c1_Iter, c2_Iter, 10 );
df_typ2 = count( c1_Iter, c2_Iter, 20 );
df_typ3 = count( c1_Iter, c2_Iter, 30 );
cout << "The number '10' is in c1 collection " << df_typ1 << " times.\n";
cout << "The number '20' is in c1 collection " << df_typ2 << " times.\n";
cout << "The number '30' is in c1 collection " << df_typ3 << " times.\n";
}
(3):iterator,const_iterator
#include
#include
int main( )
{
using namespace std;
list c1;
list ::iterator c1_Iter;
list ::reverse_iterator c1_rIter;
// If the following line replaced the line above, *c1_rIter = 40;
// (below) would be an error
//list ::const_reverse_iterator c1_rIter;
c1.push_back( 10 );
c1.push_back( 20 );
c1.push_back( 30 );
c1_rIter = c1.rbegin( );
cout << "The last element in the list is " << *c1_rIter << "." << endl;
cout << "The list is:";
for ( c1_Iter = c1.begin( ); c1_Iter != c1.end( ); c1_Iter++ )
cout << " " << *c1_Iter;
cout << endl;
// rbegin can be used to start an iteration through a list in
// reverse order
cout << "The reversed list is:";
for ( c1_rIter = c1.rbegin( ); c1_rIter != c1.rend( ); c1_rIter++ )
cout << " " << *c1_rIter;
cout << endl;
c1_rIter = c1.rbegin( );
*c1_rIter = 40;
cout << "The last element in the list is now " << *c1_rIter << "." << endl;
}
(4)size_type size( ) const;//这个是获取list的容量大小
#include
#include
int main( )
{
using namespace std;
list c1;
list ::size_type i;
c1.push_back( 5 );
i = c1.size( );
cout << "List length is " << i << "." << endl;
c1.push_back( 7 );
i = c1.size( );
cout << "List length is now " << i << "." << endl;
}
(5)value_type//这个表示list中存储元素的类型
#include
#include
int main( )
{
using namespace std;
list::value_type AnInt;
AnInt = 44;
cout << AnInt << endl;
}
(6)allocator_type
#include
#include
int main( )
{
using namespace std;
// The following lines declare objects
// that use the default allocator.
list c1;
list > c2 = list >( allocator( ) );
// c3 will use the same allocator class as c1
list c3( c1.get_allocator( ) );
list::allocator_type xlst = c1.get_allocator( );
// You can now call functions on the allocator class used by c1
}
3:List的成员函数
(1) 迭代器相关函数
begin Returniterator to beginning (public member function )
end Return iterator to end (public member function )
rbegin Return reverse iterator toreverse beginning (public member function )
rend Return reverse iterator to reverse end (public member function )
cbegin Return const_iterator to beginning (public member function )
cend Return const_iteratorto end (public member function )
crbegin Return const_reverse_iterator to reversebeginning (public member function )
crend Return const_reverse_iterator to reverse end (public member function )
const_iterator begin( ) const;
iterator begin( );
const_iterator end( ) const;
iterator end( );
const_iterator cbegin( ) const;
const_iterator cend( ) const;
const_reverse_iterator rbegin( ) const;
const_reverse_iterator rend( ) const;
这里着重接受下cbegin,cend,crbegin,crend,这几个迭代器都是指向恒定内容的,其自身的值可以变化,但是不能修改其指向的内容,下面的这段话说的很清楚,并且有示例代码。
A const_iterator is an iterator that points to const content. Thisiterator can be increased and decreased (unless it is itself alsoconst), just like the iterator returned by list::begin, but it cannot be used to modify the contents itpoints to, even if the list object is not itself const.
#include
#include
int main ()
{
std::list<</span>int
> mylist = {5,10,15,20};
std::cout <<
"mylist contains:";
for
(
autoit = mylist.cbegin(); it != mylist.cend(); ++it)
std::cout <<
' '<< *it;
std::cout <<
'\n';
return
0;
}
当用Cbegin,cend遍历元素时候,不能够修改元素的值,就是因为其实constant_iter,其指向的元素表示恒定的。
(2) 容量相关的函数
empty Test whether container isempty (public member function )
size Return size (public member function )
max_size Returnmaximum size (public member function )
bool empty( ) const;
size_type size( ) const;
size_type max_size( ) const;
这里主要说下max_size()函数,它返回的是容器的最大容量,如下:
#include
#include
int main( )
{
using namespace std;
list c1;
list ::size_type i;
i = c1.max_size( );
cout << "Maximum possible length of the list is " << i << "." << endl;
}
结果:
Maximum possible length of the list is 1073741823.
(3)元素获取
front Access first element (public member function )
back Access last element (public member function )
reference front( );
const_reference front( ) const;
(4)关于修改List以及其元素的函数
Modifiers:
assign Assign new content to container (public member function )
emplace_front Construct and insert element at beginning(public member function )
push_front Insert element at beginning (public member function )
pop_front Delete first element (public member function )
emplace_back Construct and insert element at the end(public member function )
push_back Add element at the end (public member function )
pop_back Delete last element (public member function )
emplace Construct and insert element (public member function )
insert Insert elements (public member function )
erase Erase elements (public member function )
swap Swap content (public member function )
resize Change size (public member function )
clear Clear content (public member function )
4.1 assign
template
voidassign(
InputIterator _First,
InputIterator _Last
);
void assign(
size_type_Count,
const Type&_Val
);
这个函数的作用就是擦除list中原有的所有元素,然后重新赋值,赋值就是通过上面的两个函数,要么是将一个容器的一定范围的元素赋给List,要么就是将几个相同的值赋给List。
#include
#include
int main()
{
std::list<</span>int>first;
std::list<</span>int>second;
first.assign(7,100); // 7 ints with value 100
second.assign(first.begin(),first.end()); // a copy offirst
intmyints[]={1776,7,4};
first.assign(myints,myints+3); // assigning from array
std::cout <<"Size of first: " <<int (first.size())<< '\n';
std::cout <<"Size of second: " <<int (second.size())<< '\n';
return0;
}
4.2 emplace_front
这个就是在List的段首插入一个元素
void emplace_front(
Type&&_Val
);
4.3emplace_back
这个就是在段末插入一个元素
void emplace_back(
Type&&_Val
);
#include
#include
int main()
{
std::list<std::pair<</span>int,char> >mylist;
mylist.emplace_back(10,'a');
mylist.emplace_back(20,'b');
mylist.emplace_back(30,'c');
std::cout <<"mylist contains:";
for(auto& x:mylist)
std::cout << " (" <<x.first << "," <<x.second << ")";
std::cout <<std::endl;
return0;
}
4.4 emplace
这个就是在指定的位置插入一个元素
void emplace_back(
iterator_Where,
Type&&_Val
);
#include
#include
int main()
{
std::list<std::pair<</span>int,char> >mylist;
mylist.emplace (mylist.begin(), 100, 'x' );
mylist.emplace (mylist.begin(), 200, 'y' );
std::cout <<"mylist contains:";
for(auto& x:mylist)
std::cout << " (" <<x.first << "," <<x.second << ")";
std::cout <<'\n';
return0;
}
Output:
Output:
mylist contains: (200,y) (100,x)
4.5 push_front
这个函数和emplace_front 类似,同理push_back和emplace_back类似,但是其的区别也是很明显的,emplace系列的函数是直接构造元素然后再插入的,但是push系列的函数是通过复制或者移动存在的元素。
voidpush_front(
const Type&_Val
);
voidpush_front(
Type&&_Val
);
4.6 push_back
这个函数顾名思义就在在List的末尾插入一个元素
voidpush_back(
voidpush_back(
Type&&_Val
);
4.7 insert
Insert可以实现在任意的位置插入一个或者多个元素
iteratorinsert(
const_iterator_Where,
const Type&_Val
);
iteratorinsert(
const_iterator_Where,
Type&&_Val
);
void insert(
iterator_Where,
size_type_Count,
const Type&_Val
);
template
voidinsert(
iterator _Where,
InputIterator _First,
InputIterator _Last
);
// inserting into a list
#include
#include
#include
int main()
{
std::list<</span>int>mylist;
std::list<</span>int>::iterator it;
// set someinitial values:
for(int i=1;i<=5; ++i) mylist.push_back(i); // 1 2 3 45
it = mylist.begin();
++it; // it points now to number2 ^
mylist.insert(it,10); // 1 10 2 3 45
// "it" stillpoints to number2 ^
mylist.insert(it,2,20); // 1 10 20 20 2 3 4 5
--it; // it points now to the second20 ^
std::vector<</span>int>myvector (2,30);
mylist.insert(it,myvector.begin(),myvector.end());
// 1 10 20 30 30 20 2 3 4 5
// ^
std::cout <<"mylist contains:";
for(it=mylist.begin(); it!=mylist.end();++it)
std::cout << ' ' <<*it;
std::cout <<'\n';
return0;
}
Output:
mylist contains: 1 10 20 30 30 20 2 3 45 |
4.8 pop_front
删除容器中的第一个元素,同时容器的大小自动减1。
void pop_front();
4.9 pop_back
删除容器中的最后一个元素,同时容器的大小自动减1
void pop_back();
4.10 erase
移除容器中的一个或者多个元素,同时容器的大小自动的减小相应的大小。
iterator erase(
iterator _Where
);
iterator erase(
iterator _First,
iterator _Last
);
函数的返回的是一个迭代器,它指向被删除的最后一个元素的紧挨着的元素。下面的程序很好的说明了erase函数的用法,其中的“^”表示迭代器的指向位置。
#include
#include
int main ()
{
std::list<</span>int
> mylist;
std::list<</span>int
>::iterator it1,it2;
// set some values:
for
(
inti=1; i<10; ++i) mylist.push_back(i*10);
// 10 20 30 40 50 60 70 80 90
it1 = it2 = mylist.begin();
// ^^
advance (it2,6);
// ^ ^
++it1;
// ^ ^
it1 = mylist.erase (it1);
// 10 30 40 50 60 70 80 90
// ^ ^
it2 = mylist.erase (it2);
// 10 30 40 50 60 80 90
// ^ ^
++it1;
// ^ ^
--it2;
// ^ ^
mylist.erase (it1,it2);
// 10 30 60 80 90
// ^
std::cout <<
"mylist contains:";
for
(it1=mylist.begin(); it1!=mylist.end(); ++it1)
std::cout <<
' '<< *it1;
std::cout <<
'\n';
return
0;
}
4.11 clear
Void clear()
擦除List中所有的元素。
4.12 resize
void resize(
size_type _Newsize
);
void resize(
size_type _Newsize,
Type _Val
);
当_Newsize大于原容器的大小时,多余的元素会被_val替代,若没有指定_val,会调用默认的构造函数。
#include
#include
int main ()
{
std::list<</span>int
> mylist;
// set some initial content:
for
(
inti=1; i<10; ++i) mylist.push_back(i);
mylist.resize(5);
mylist.resize(8,100);
mylist.resize(12);
std::cout <<
"mylist contains:";
for
(std::list<</span>int
>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout <<
' '<< *it;
std::cout <<
'\n';
return
0;
}
结果:mylist contains: 1 2 3 4 5 100 100 100 0 0 0 0
4.13 swap
void swap(
list& _Right
);
friend void swap(
list& _Left,
list& _Right
)
交换两个相同类型的List的内容,List中的type和allocator Type都要一致。
(5)List操作相关的函数
5.1 splice
void splice(
iterator _Where,
list& _Right
);
void splice(
iterator _Where,
list& _Right,
iterator _First
);
void splice(
iterator _Where,
list& _Right,
iterator _First,
iterator _Last
);
两个List相互铰接,切记操作完成后两个List中元素总和不变,所以第一个函数调用后,Right变空,第二个函数调用后,Right中少了Iter所指的元素。
#include
#include
int main ()
{
std::list<</span>int
> mylist1, mylist2;
std::list<</span>int
>::iterator it;
// set some initial values:
for
(
inti=1; i<=4; ++i)
mylist1.push_back(i);
// mylist1: 1 2 3 4
for
(
inti=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;
}
5.2 remove
void remove (const value_type& val);
删除指定值大小的元素。
5.3 remove_if
template
void remove_if(
Predicate _Pred
)
The function calls pred(*i) for each element (where i is an iterator to that element). Any of theelements in the list for which this returns true, are removed from thecontainer.,
_Pred
Unary predicate that, taking a value of the same type asthose contained in the forward_list object,returns truefor those values to beremoved from the container, and false for those remaining.
This can either be a function pointer or a functionobject.
就是说这个_Pred元素必须是一个函数指针或者 函数对象。
#include
#include
// a predicate implemented as a function:
boolsingle_digit (
constint
& value) {
return(value<10); }
// a predicate implemented as a class:
struct is_odd {
bool
operator
() (
constint
& value) {
return(value%2)==1; }
};
int main ()
{
int
myints[]= {15,36,7,17,20,39,4,1};
std::list<</span>int
> mylist (myints,myints+8); // 15 36 7 17 20 39 4 1
mylist.remove_if (single_digit);
// 15 36 17 20 39
mylist.remove_if (is_odd());
// 36 20
std::cout <<
"mylist contains:";
for
(std::list<</span>int
>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout <<
' '<< *it;
std::cout <<
'\n';
return
0;
}
5.4 unique
void unique( );
template
void unique(
BinaryPredicate _Pred
);
下面的源码讲了怎么调用
/ list::unique
#include
#include
#include
// a binary predicate implemented as a function:
boolsame_integral_part (
doublefirst,
doublesecond)
{
return(
int(first)==
int(second) ); }
// a binary predicate implemented as a class:
struct is_near {
bool
operator
() (
doublefirst,
doublesecond)
{
return(fabs(first-second)<5.0); }
};
int main ()
{
double
mydoubles[]={ 12.15, 2.72, 73.0, 12.77, 3.14,
12.77, 73.35, 72.25, 15.3, 72.25 };
std::list<</span>double
> mylist (mydoubles,mydoubles+10);
mylist.sort();
// 2.72, 3.14, 12.15, 12.77, 12.77,
// 15.3, 72.25, 72.25, 73.0, 73.35
mylist.unique();
// 2.72, 3.14, 12.15, 12.77
// 15.3, 72.25, 73.0, 73.35
mylist.unique (same_integral_part);
// 2.72, 3.14, 12.15
// 15.3, 72.25, 73.0
mylist.unique (is_near());
// 2.72, 12.15, 72.25
std::cout <<
"mylist contains:";
for
(std::list<</span>double
>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout <<
' '<< *it;
std::cout <<
'\n';
return
0;
}
5.5 merge
void merge(
list& _Right
);
template
void merge(
list& _Right,
Traits _Comp
);
Merge和splice有点相似,不过merge是排序的。
#include
#include
// compare only integral part:
boolmycomparison (
doublefirst,
doublesecond)
{
return(
int(first)<</span>int
(second) ); }
int main ()
{
std::list<</span>double
> first, second;
first.push_back (3.1);
first.push_back (2.2);
first.push_back (2.9);
second.push_back (3.7);
second.push_back (7.1);
second.push_back (1.4);
first.sort();
second.sort();
first.merge(second);
// (second is now empty)
second.push_back (2.1);
first.merge(second,mycomparison);
std::cout <<
"first contains:";
for
(std::list<</span>double
>::iterator it=first.begin(); it!=first.end(); ++it)
std::cout <<
' '<< *it;
std::cout <<
'\n';
return
0;
}
5.6 get_allocator
allocator_type get_allocator() const;
#include
#include
int main ()
{
std::list<</span>int
> mylist;
int
* p;
// allocate an array of 5 elements using mylist's allocator:
p=mylist.get_allocator().allocate(5);
// assign some values to array
for
(
inti=0; i<5; ++i) p[i]=i;
std::cout <<
"The allocated array contains:";
for
(
inti=0; i<5; ++i) std::cout <<
' '<< p[i];
std::cout <<
'\n';
mylist.get_allocator().deallocate(p,5);
return
0;
}
5.6 =
#include
#include
int main ()
{
std::list<</span>int
> first (3); // list of 3 zero-initialized ints
std::list<</span>int
> second (5); // list of 5 zero-initialized ints
second = first;
first = std::list<</span>int
>();
std::cout <<
"Size of first: "<<
int(first.size()) <<
'\n';
std::cout <<
"Size of second: "<<
int(second.size()) <<
'\n';
return
0;
}
写到这里终于把所有List的函数用法都写完了,呵呵,还真不少,不过用起来真方便。