- vector
- dequeue / list
- forward_list
- set / map / unoreder_set / unordered_map
위 4가지 종류의 STL 컨테이너들에는 emplace 기능을 제공해 주는 함수가 존재합니다.
STL 컨테이너별 emplace 함수 목록
1) vector
- emplace
- emplace_back
2) deque / list
- emplace
- emplace_back
- emplace_front
3) forward_list
- emplace_front
- emplace_after
4) set / map / unoreder_set / unordered_map
- emplace
- emplace_hint
이 함수가 무엇이고 어떻게 사용해야 하는지 같이 살펴봅시다.
emplace 함수란
emplace 함수는 map.insert()와 같이 컨테이너 안에 객체를 추가해 주는 함수입니다.
map.insert()와 map.emplace()의 실행 결과는 완전히 동일합니다.
하지만 결과까지 가는 연산 과정에서 차이가 존재합니다.
차이점
emplace은 컨테이너값을 추가할 때 내부에서 값을 생성한다는 차이점을 가지고 있습니다.
이에 대해 자세히 살펴보기 위해 아래 예제 코드를 실행시켜 보겠습니다.
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct President
{
string name;
string country;
int year;
President(string p_name, string p_country, int p_year)
: name(move(p_name)), country(move(p_country)), year(p_year)
{
cout << "I am being constructed.\n";
}
President(const President &other)
: name(move(other.name)), country(move(other.country)), year(other.year)
{
cout << "I am being copied.\n";
}
President(President &&other)
: name(move(other.name)), country(move(other.country)), year(other.year)
{
cout << "I am being moved.\n";
}
~President()
{
cout << "I am being destructed.\n";
}
President &operator=(const President &other) = default;
};
int main()
{
// VS2013의 emplace_back
// vector 내부에서 생성 -> 컨테이터에 추가하기에 임시 객체 생성 X
vector<President> elections;
elections.emplace_back("Nelson Mandela", "South Africa", 1994);
cout << '\n';
// VS2010의 emplace_back 역시 아래 push_back과 동일한 방식으로만 사용이 가능했었다
// 외부에서 생성 -> 벡터로 이동 -> 외부 객체 파괴가 발생한다
vector<President> reElections;
reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
cout << '\n';
for (President const &president : elections)
{
cout << president.name << " was elected president of "
<< president.country << " in " << president.year << ".\n";
}
for (President const &president : reElections)
{
cout << president.name << " was re-elected president of "
<< president.country << " in " << president.year << ".\n";
}
}
//cppreference.com 예제 참조
코드 실행 결과
I am being constructed.
I am being constructed.
I am being moved.
I am being destructed.
Nelson Mandela was elected president of South Africa in 1994.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.
I am being destructed.
I am being destructed.
예제 코드를 실행시켜 보면 알 수 있듯이
emplace_back() 함수를 사용할 경우 생성자 한 번만이 호출되는 반면
push_bakc() 함수를 사용할 경우 생성자 두 번과 소멸자 한 번이 호출되는 것을 확인해 볼 수 있습니다.
따라서 컨테이너에 추가할 때 객체를 생성할 경우에는 emplace_back()을 사용하는 것이 보다 좋습니다.
'Language & FrameWork > C++' 카테고리의 다른 글
[C++] strtok() 함수를 활용하여 문자열 토크나이징하기 (0) | 2020.10.02 |
---|---|
[C++] std::advance(),std::distance() 임의 접근 생성자 (0) | 2020.05.04 |
& 참조형 변수 (0) | 2020.03.22 |
[C++] 메모리 관리 방법 정리 (0) | 2020.03.17 |