push_back을 뜯어보면, 다음과 같은 step을 거친다.

1. push_back을 통해 객체를 삽입하기 위해, item 임시 객체를 하나 만듭니다.
2. 임시 객체를 복사 생성자를 통해 push_back 함수 내에서 임시 객체를 만들어 냅니다.
3. 함수내에 만들어진 임시 객체를 vector 의 끝에 추가합니다.
4. 함수를 빠져나온 후, push_back에 삽입하기 위해 만들었던 (1번) item 임시 객체를 소멸시킵니다.
(출저 : https://openmynotepad.tistory.com/10?category=853099)

보면 push_back 실행 직전 삽입할 임시 객체 하나 (step 1), 함수 내에서 한번 더 (step 2) 총 2번 생성하는 것을 볼 수 있다.

 

아니 굳이 왜 두 번이나 생성하지? 그냥 한 번만 만들어서 바로 삽입만 하면 되는거 아닌가?

즉, 첫번째 임시 객체를 생성할 필요 없이 그냥 값을 두번째 임시 객체에 바로 넘겨주면 실행 과정을 더 최적화 할 수 있지 않을까?

 

이미 push_back 함수에는 rvalue reference를 받아서 move를 구현해주는 형태가 overloading 되어있다.

(1)처럼 lvalue를 넘겨주면 위의 1~4 과정을 다 거치고, (2)처럼 rvalue를 넘겨주면 2~3 과정만 거치는 듯 하다.

 


C++11에선 emplace_back이라는 함수가 추가됐다.

 

push_back에서 추가하고자 하는 객체를 직접 넘겨줬다.

ex) vector<Item> v; v.push_back(Item("Hello", 5));

 

emplace_back은 객체 생성에 필요한 argument들을 넣어주면, 함수가 알아서 객체의 constructor를 호출해서 2~3과정을 거친다.

ex) vector<Item> v; v.emplace_back("Hello", 5);

 

 

Q. 아니 그러면 rvalue reference 받는 push_back이랑 똑같은거 아니에요?

> 하는 일은 같음. 근데 push_back은 객체를, emplace_back은 construction에 필요한 argument를 인자로 받는다는 차이가 있음. 귀찮게 매번 move써서 rvalue reference push_back 쓸 필요 없잖아?

또, rvalue reference push_back을 쓰려면, 객체에 '이동 생성자 (move constructor)'가 정의되어있어야 할 듯.

https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back 

 

난 vector<pair<int, int>> 같은 경우엔 emplace_back을, 

간단한 vector<int> 같은 경우는 그냥 push_back을 쓴다.

Initialize 가 큰 객체를 다룰 땐 emplace_back을 애용하자 (rvalue ref push_back 쓰려면 객체의 이동 생성자 만들어줘야 하니 귀찮잖아)

 

이런 이야기도 있다

사실 push_back 함수를 사용할 경우 컴파일러가 알아서 최적화를 해주기 때문에 불필요한 복사-이동을 수행하지 않고 emplace_back 을 사용했을 때와 동일한 어셈블리를 생성합니다. 따라서 push_back 을 사용하는 것이 훨씬 낫습니다. (emplace_back 은 예상치 못한 생성자가 호출될 위험이 있습니다)

 

 

참고한 블로그 : https://openmynotepad.tistory.com/10?category=853099 


Q. 아래 링크 예제 코드를 보면, map<int, string> 원소들을 vector<pair<int, string>> 으로 옮길 때,

그냥 v.push_back.(kv.second)가 아닌, v.push_back(move(kv.second))를 쓰고 있다.  

-> push_back 이전에 string 임시객체 다시 생성하는걸 막는 걸 뿐.

string이 현재 lvalue이므로 그냥 push_back에 넣어주면 rvalue 임시객체 만들어야 함. 그래서 move로 rvalue로 바꾸고 넣어준 것

https://stackoverflow.com/questions/42282382/c-copy-map-to-vector-with-stdmove

push_back vs emplace_back 정리 블로그에도 나온다 (맨 아래 참고한 블로그)

+ Recent posts