이 글에서는 C++ STL에서 list::emplace_front()와 list::emplace_back() 함수의 작동 방식, 문법, 그리고 실제 코드 예제를 통해 리스트의 앞과 뒤에 요소를 효율적으로 삽입하는 방법을 자세히 알아보겠습니다.
STL에서 리스트(List)란 무엇인가?
리스트는 시퀀스의 어느 위치에서든 상수 시간(O(1))에 삽입과 삭제를 수행할 수 있는 자료구조입니다. 리스트는 내부적으로 이중 연결 리스트(doubly linked list)로 구현되어 있으며, 비연속적인 메모리 할당을 허용합니다.
리스트는 배열(array), 벡터(vector), 덱(deque)에 비해 컨테이너의 임의 위치에서 요소를 삽입, 추출, 이동하는 작업에서 훨씬 더 나은 성능을 보입니다. 다만 요소에 직접 접근(임의 접근)하는 속도는 느린 편입니다. 리스트는 forward_list와 유사하지만, forward_list는 단일 연결 리스트(singly linked list)이기 때문에 앞 방향으로만 순회할 수 있다는 차이가 있습니다.
list::emplace_front()란?
list::emplace_front()는 C++ STL의 내장 함수로, <list> 헤더 파일에 선언되어 있습니다. 이 함수는 리스트 컨테이너의 맨 앞에 요소를 삽입하는 데 사용됩니다.
- 컨테이너가 비어 있는 경우: 요소가 첫 번째 위치에 삽입되어 해당 요소가 첫 번째 요소가 됩니다.
- 컨테이너에 요소가 이미 있는 경우: 전달된 요소가 맨 앞에 삽입되고, 기존의 첫 번째 요소는 두 번째 요소가 됩니다.
이 함수는 호출될 때마다 컨테이너의 크기를 1 증가시킵니다. 또한 임시 객체를 생성한 후 복사하거나 이동하는 push_front()와 달리, emplace 계열 함수는 전달된 인자를 사용해 컨테이너 내부에서 직접 객체를 생성하므로 불필요한 복사 비용을 줄일 수 있다는 장점이 있습니다.
문법
listname.emplace_front(const value_type& element1);
listname.emplace_front(value_type&& element1);
매개변수
이 함수는 삽입할 요소 1개만 인자로 받습니다.
반환값
이 함수는 아무것도 반환하지 않습니다(void).
예제 1
Input: list<int> mylist = {1, 2, 3, 4};
mylist.emplace_front(0);
Output:
List elements are = 0 1 2 3 4
예제 2
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int> List;
List.emplace_front(10);
List.emplace_front(20);
List.emplace_front(30);
List.emplace_front(40);
List.emplace_front(50);
List.emplace_front(60);
cout<<"Elements are : ";
for(auto i = List.begin(); i!= List.end(); ++i)
cout << ' ' << *i;
return 0;
}
실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Elements are : 60 50 40 30 20 10
출력 결과에서 알 수 있듯이, emplace_front()는 호출될 때마다 요소를 맨 앞에 추가하기 때문에 나중에 삽입한 값일수록 앞쪽에 위치하게 됩니다.
list::emplace_back()란?
list::emplace_back() 역시 C++ STL의 내장 함수로, <list> 헤더 파일에 선언되어 있습니다. 이 함수는 리스트 컨테이너의 맨 뒤(끝)에 요소를 삽입하는 데 사용됩니다.
- 컨테이너가 비어 있는 경우: 단순히 요소를 삽입하며 컨테이너의 크기가 1이 됩니다.
- 컨테이너에 요소가 이미 있는 경우: 전달된 요소가 리스트의 맨 끝에 추가됩니다.
이 함수 역시 호출될 때마다 컨테이너의 크기를 1 증가시키며, push_back()과 달리 객체를 컨테이너 내부에서 직접 생성하므로 복사·이동 오버헤드를 줄일 수 있습니다.
문법
listname.emplace_back(const value_type& element1);
listname.emplace_back(value_type&& element1);
매개변수
이 함수는 삽입할 요소 1개만 인자로 받습니다.
반환값
이 함수는 아무것도 반환하지 않습니다(void).
예제 1
Input: list<int> list1 = {1, 2, 3, 4};
list1.emplace_back(5);
Output: List: 1 2 3 4 5
예제 2
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int> List;
List.emplace_back(10);
List.emplace_back(20);
List.emplace_back(30);
List.emplace_back(40);
List.emplace_back(50);
List.emplace_back(60);
cout<<"elements are : ";
for(auto i=List.begin(); i!= List.end(); ++i)
cout << ' ' << *i;
return 0;
}
실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Elements are : 10 20 30 40 50 60
emplace_back()은 호출 순서대로 요소를 맨 뒤에 추가하기 때문에 삽입한 순서 그대로 출력되는 것을 확인할 수 있습니다.
emplace_front()와 emplace_back()의 차이점 요약
| 구분 | emplace_front() | emplace_back() |
|---|---|---|
| 삽입 위치 | 리스트의 맨 앞 | 리스트의 맨 뒤 |
| 시간 복잡도 | O(1) | O(1) |
| 반환값 | 없음(void) | 없음(void) |
| 크기 변화 | 1 증가 | 1 증가 |
두 함수 모두 상수 시간에 동작하며, 리스트의 양방향 연결 리스트 구조 덕분에 앞이나 뒤 어느 쪽에 삽입하더라도 성능 차이가 없습니다. 상황에 맞게 적절한 함수를 선택해 사용하면 됩니다.