최근 vector를 사용하면서 데이터 삽입을 할때 emplace_back과 push_back을 사용했다. 이 둘의 차이점이 궁금해져서 이번에 한번 정리해보겠다.
https://openmynotepad.tistory.com/10
=> 나는 이 블로그를 참고했다
push_back과 emplace_back 둘 다 실질적으로 수행하는 일은 "컨테이너의 끝에 요소를 추가하는 것"이다. 하지만 두 함수를 memory allocation 관점에서 보면 emplace_back이 훨씬 효율적으로 작동한다.
push_back 함수는 '객체' 를 집어 넣는 형식으로, 객체가 없이 삽입을 하려면 "임시객체 (rvalue) " 가 있어야한다.
즉 객체를 삽입하기 위해서 똑같은 임시 객체를 하나 더 만들어서 거기에 복사한 다음 벡터에 삽입 ->삽입이 끝나면 임시 객체 파괴
잠깐 쓰고 버릴 메모리를 굳이 할당해야하고 임시 객체 생성자를 호출해서 생성하고 소멸자를 불러서 파괴시키는 과정에서 불필요한 연산이 생긴다. => 비효율적
emplace_back은 벡터에 메모리 할당을 하는 동시에 값을 삽입하는 것이 가능하다.
emplace_back은 가변인자 템플릿을 사용해서 객체 생성에 필요한 인자만 받은 후, 삽입하려는 자료형에 따라 함수 내에서 객체를 생성 및 이동을 통해 element를 생성한다. 임시 객체를 만들 필요가 없기 때문에, emplace_back 내부에서 삽입에 필요한 생성자 한번만 호출된다. 다시 말해, 불필요한 임시 객체의 생성과 파괴 과정없이 효율적으로 벡터 element를 추가한다. => 효율적
또 다른 차이가 있는데 push_back은 메모리 할당을 하지 않고 데이터를 삽입하기 때문에 벡터에 값을 삽입하려면 완성된 객체가 있어야 삽입이 가능. 그렇기 때문에 인자값과 똑같은 임시 객체를 만들기 때문에, 그냥 뒤에 곧바로 추가할 수 있는 emplace_back이 있다.
그럼 그냥 emplace_back만 쓰면 되는 것일까?
정답은 아니다. 아래의 예제를 보면 알 수 있다.
v.push_back(100);
v.emplace_back(100);
위의 코드만 봤을 때, push_back의 경우 명확하다. 숫자 100을 vector에 추가한다는 것을 나타내지만, emplace_back의 경우 확실히 알 수 없다.
만약 vector가 vector<vector>의 형태인 경우, 100개의 요소를 메모리에 할당하게 된다. push_back을 사용했을 경우 complile error를 통해 complie 시점에 개발자가 인지하고 고칠 수 있지만, emplace_back의 경우 개발자가 의도하지 않은 결과를 초래하게 될 수 있다.
그러니 상황에 맞게 사용하면 될 것 같다.