[ ] 이론적으로, emplcement 함수들은 종종 insertion 버전보다 더 효율적이어야하며, 덜 효율적이어서는 안된다
[ ] 다음과 같은 조건에서 insertion 보다 emplcement 함수가 빠를 가능성이 매우 크다.
(1) 추가되는 값이 컨테이너에서 생성됨 - 할당되지X
(2) 전달된 인수 형식이 컨테이너의 유형과 다름
(3) 추가하려는 값이 중복된 값이어도 컨테이너가 거부하지 않을 때
[ ] insertion 함수를 사용했을 때 거부당했더라도 emplacement 함수는 해당 형식 변환들을 수행 가능하다.
push_back()
- 컨테이너가 담는 형식이 정해져있음!
emplace_back()
- 컨테이너 형식과 독립적! T와 다른 Args가 있어 호출될 때마다 연역되어야 함.(item24 참고)
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int main(){
vector<string> vs; //string 컨테이너에
vs.push_back("xyz"); // 문자열 리터럴을 추가해보자
//일치하지 않으므로 컴파일러가 다음처럼 생각함
vs.push_back(string("xyz"));
}
위에 의해서 일어나는 일은 다음과 같다.
Step1. 임시객체 string(“xyz”)
가 생성된다.
Step2. 임시객체가 오른값으로 value에 전달 → vector를 위한 메모리 안에서 value 를 위한 자리를 만들고 value는 오른값 참조이기 때문에 이동생성
Step3. push_back이 반환되면 임시객체 소멸, vs가 끝나면 내부에서 소멸
$\therefore$ vector 안에 T 객체를 생성하는 부분에 문자열 리터럴을 직접 전달할 수 있다면 1번만 생성소멸 할텐데…
emplace_back()은 주어진 인수를 이용하여 vector 안에서 직접 T를 생성하며 임시 객체는 관여하지 않음!
vs.emplace_back("abc"); //"abc"를 이용하여 직접 벡터 안에서 생성
push_back()
을 지원하는 모든 표준 컨테이너는 emplace_back()
을 지원. 나머지도 비슷함.
+) 인터페이스가 유연 : 삽입할 객체의 생성자를 위한 인수들을 받아옴!