template<
    class Ty,
    class Allocator = std::allocator<Ty>
> class list;

   list는 이중 연결리스트를 구현한 컨테이너이다. <list> 헤더에 구현되어 있다. forward_list에 비해 더 많은 메모리를 사용하지만, 더 양방향 이동이 가능한다.


 

1. 사용

생성

다양한 방법을 이용해 생성 가능하다. 빈 컨테이너를 생성하거나, 미리 요소가 추가된 컨테이너를 생성할 수 있다. 각 생성자들은 Allocator를 추가적으로 받을 수 있다.

  1. 기본 생성자
  2. size를 전달하는 생성자
  3. initializer_list를 전달하는 생성자
  4. 시작과 끝의 이터레이터를 전달하는 생성자
  5. 복사 생성자
  6. 이동 생성자
// 1.	기본 생성자
//		아무것도 할당되지 않은 상태로 초기화.
list<int> list1;

// 2.	size를 전달 받는 생성자.
//		size만큼의 기본 값을 갖는 node를 리스트에 추가함.
list<int> list2(5);						// 0 0 0 0 0

// 2-2.	size와 초기화 값 v을 받는 생성자
//		size만큼의 v값을 갖는 node를 리스트에 추가함.
list<int> list2_2(5, 1);					// 1 1 1 1 1

// 3.	initializer_list
list<int> list3 = { 1,2,3,4,5 };		// 1 2 3 4 5
list<int> list3_2{ 1,2,3,4,5 };
list<int> list3_3({ 1,2,3,4,5 });

// 4.	iterator
list<int> list4(list3.begin(), list3.end());	// 1 2 3 4 5;

// 5.	copy
list<int> list5(list4);					// 1 2 3 4 5

// 6. move
list<int> list6(move(list5));			// 1 2 3 4 5

접근

접근 메서드로는 시작과 마지막 요소의 레퍼런스를 반환하는 front()back()만을 지원한다.

list<int> c{ 1,2,3,4,5 };
int& f = c.front();	// 1
int& b = c.back();	// 5
f = -1;				// -1 2 3 4 5
b = 10;				// -1 2 3 4 100

이터레이터

++--를 이용해 이동할 수 있다.


용량

   size()를 이용해 현재 보관된 요소의 개수를 알 수 있다. 그 외의 컨테이너가 비어있는지 확인할 수 있는 empty()와 총 삽입 가능한 크기를 알려주는 max_size()를 제공한다.

list<int> c{1,2,3,4,5};
c.size();           // 5
c.empty();		//false
c.max_size();	// 가용 가능한 메모리 총량

수정

   insert()emplace를 통해 원하는 위치에 요소를 삽입할 수 있다. insert()로는 1개 이상의 요소를 한 번에 삽입 가능하다. 원하는 위치의 요소 삭제는 erase()를 이용한다. push_back(), push_front(), empace_back(), emplace_front()로 컨테이너 양쪽 끝 단에 요소를 삽입할 수 있다. pop_back()pop_front()로 컨테이너 양쪽 끝단에 있는 요소를 삭제할 수 있다.

list<int> c{ 1,2,3,4,5 };

auto iter = c.begin();
iter = next(iter, 2);			// 3
iter = c.insert(iter, 11);		// 1 2 11 3 4 5
iter = c.insert(iter, 12);		// 1 2 12 11 3 4 5

iter = c.end();
c.emplace(iter, 6);		// 1 2 12 11 3 4 5 6
c.emplace(iter, 7);		// 1 2 12 11 3 4 5 6 7

iter = next(c.begin(), 2);		// 12
iter = c.erase(iter);			// 1 2 11 3 4 5 6 7
c.erase(iter);					// 1 2 3 4 5 6 7

c.push_front(99);				// 99 1 2 3 4 5 6 7
c.push_back(10);				// 99 1 2 3 4 5 6 7 10

c.emplace_front(-1);			// -1 99 1 2 3 4 5 6 7 10
c.emplace_back(-99);			// -1 99 1 2 3 4 5 6 7 10 -99

c.pop_back();					// -1 99 1 2 3 4 5 6 7 10
c.pop_back();					// -1 99 1 2 3 4 5 6 7
c.pop_back();					// -1 99 1 2 3 4 5 6 
c.pop_front();					// 99 1 2 3 4 5 6
c.pop_front();					// 1 2 3 4 5 6

   resize로 보관된 요소의 수를 줄이거나, 일정한 값으로 채워 늘릭 수 있다. clear()를 사용해 요소를 비울 수 있다.

//c ==>  1 2 3 4 5 6
c.resize(3, 0);					// 1 2 3
c.resize(5);					// 1 2 3 0 0
c.clear();						// empty
c.resize(5, 1);					// 1 1 1 1 1

기타

   list역시 forward_list와 마찬가지로 사용할 수 있는 독특한 연산이나, 이터레이터를 만족하지 못해서 사용할 수 없던 <algorithm>의 함수들을 내부 메서드로 지원한다.

  • remove(e) : e와 같은 요소들을 제거하고, 제거된 수를 반환한다.
  • remove_if(f) : 요소가 함수 f를 만족하면 제거하고, 제거된 수를 반환한다.
  • reverse() : 리스트의 순서를 뒤집는다.
  • unique() : 연속적으로 같은 값이 반복되어 있다면 하나를 제외하고 제거한다.
  • sort() : 리스트를 정렬한다.
  • merge() : 정렬된 두 리스트를 순서를 유지하며 합친다.
  • splice_after() : 다른 리스트를 가져와 이동시킨다.
list<int> c{ 3,3,9,2,3,4,1,1,7,8 };


auto n = c.remove(1);		// 3 3 9 2 3 4 7 8
n;							// 2

// 5보다 크면 삭제한다.		// 3 3 2 3 4
n = c.remove_if([](int v) { return v > 5; });
n;							// 3

c.reverse();				// 4 3 2 3 3

n = c.unique();				// 4 3 2 3
n;							// 1

c.push_front(5);			// 5 4 3 2 3
c.sort();					// 2 3 3 4 5


list<int> c2{ 0,1,10,11,12 };
// c2는 이동되어 empty가 된다.
c.merge(c2);				// 0 1 2 3 3 4 5 10 11 12

c.resize(4);				// 0 1 2 3
c2.assign({ 7,8,9 });		// 7 8 9

// c2는 이동된다. (c2가 empty가 된다.)
c.splice(c.begin(), c2);	// 7 8 9 0 1 2 3