이 글에서는 C++에서 forward_list::emplace_after()와 forward_list::emplace_front() 함수가 어떻게 동작하는지 자세히 살펴보겠습니다.
forward_list는 일반적인 list와 달리 다음(next) 요소와의 연결만 유지하는 단방향 연결 리스트입니다. 일반 list는 앞뒤 요소 모두와 연결되어 있어 양방향 순회가 가능하지만, forward_list는 앞쪽(정방향)으로만 순회할 수 있습니다. 대신 이러한 단순한 구조 덕분에 메모리 사용량이 적고 오버헤드가 낮다는 장점이 있습니다.
두 함수 모두 C++ 표준 라이브러리에 포함되어 있으며, 각각 다음과 같은 역할을 수행합니다.
- emplace_after() – 인수로 지정된 위치의 요소 바로 뒤에 새 요소를 삽입합니다.
- emplace_front() – 리스트의 맨 앞에 새 요소를 삽입합니다.
이 함수들을 호출하려면 <forward_list> 헤더 파일을 포함해야 합니다.
forward_list::emplace_after()
문법
Forward_List_Name.emplace_after(iterator, element);
매개변수
이 함수는 두 개의 매개변수를 받습니다.
- iterator – 새 요소가 삽입될 기준 위치를 담고 있는 반복자입니다. 전달된 반복자가 가리키는 요소 바로 뒤에 새 요소가 추가됩니다.
- element – 해당 위치에 삽입할 요소입니다.
반환값
새로 삽입된 요소를 가리키는 반복자를 반환합니다.
주의 사항
emplace_after()에는 리스트 내부의 유효한 반복자를 전달해야 합니다. 끝을 넘어선(end()) 반복자를 전달하면 정의되지 않은 동작(undefined behavior)이 발생할 수 있으므로 주의해야 합니다.
forward_list::emplace_front()
문법
Forward_List_Name.emplace_front(element);
매개변수
삽입할 요소 하나를 매개변수로 받습니다.
반환값
반환값이 없습니다(void).
참고: emplace 계열 함수의 장점
emplace_front(), emplace_after()는 전달된 인수를 사용해 요소를 컨테이너 내부에서 직접 생성(in-place construction)합니다. push_front(), insert_after()처럼 기존 객체를 복사하거나 이동하지 않기 때문에, 복사 비용이 큰 객체를 다룰 때 성능 면에서 유리합니다.
예제
입력: 11, 34, 56
출력: 41 11 34 56
설명:
요소 11, 34, 56을 가진 forward_list Lt를 생성한 뒤, emplace_front() 함수를 호출해 리스트 맨 앞에 새 요소 41을 삽입했습니다. 따라서 리스트를 출력하면 첫 번째 요소가 41인 41 11 34 56이 출력됩니다.
예제 프로그램의 접근 방식
- 먼저 int 타입의 forward_list(예: "Lt")를 생성하고 값을 할당합니다.
- emplace_front() 함수를 호출하여 리스트 맨 앞에 새 요소를 삽입합니다.
- auto 타입의 반복자(예: "itr")를 만들어 emplace_after()에 전달할 위치를 저장합니다. 여기서는 리스트의 마지막 요소를 가리키도록 설정합니다.
- emplace_after() 함수를 호출하여 지정한 위치 뒤에 요소를 삽입합니다. 첫 번째 인수는 리스트 내 위치를 지정하는 반복자 "itr", 두 번째 인수는 그 위치에 삽입할 요소입니다.
알고리즘
시작
Step 1 -> main() 함수 진입
Step 2 -> forward_list<int> Lt = {5,6,7,8} 초기화
Step 3 -> Lt.emplace_front(3) 호출하여 맨 앞에 요소 삽입
Step 4 -> 마지막 요소를 가리키는 반복자 itr 획득
Step 5 -> Lt.emplace_after(itr, 10) 호출하여 itr 뒤에 요소 삽입
Step 6 -> 리스트 전체 출력
종료
구현 예제
#include <iostream>
#include <forward_list>
using namespace std;
int main() {
forward_list<int> Lt = { 5, 6, 7, 8 };
// emplace_front() 함수로 리스트 맨 앞에 요소 삽입
Lt.emplace_front(3);
// 마지막 요소를 가리키는 반복자 구하기
auto itr = Lt.begin();
while (next(itr) != Lt.end())
++itr;
// emplace_after() 함수로 itr 위치 뒤에 요소 삽입
Lt.emplace_after(itr, 10);
// 리스트 출력
for (int x : Lt)
cout << x << " ";
return 0;
}
출력
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
3 5 6 7 8 10
먼저 emplace_front(3)에 의해 3이 리스트 맨 앞에 추가되고, 이어서 emplace_after(itr, 10)에 의해 마지막 요소 8 뒤에 10이 추가되어 최종적으로 3 5 6 7 8 10이라는 결과가 만들어집니다.