[Modern C++][C++11] push_back vs emplace_back
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 쓰려면 객체의 이동 생성자 만들어줘야 하니 귀찮잖아)
이런 이야기도 있다
참고한 블로그 : 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 정리 블로그에도 나온다 (맨 아래 참고한 블로그)
'<언어> > [C++]' 카테고리의 다른 글
[C++] enum vs enum class (0) | 2022.01.20 |
---|---|
[Modern C++][C++17] Structured Binding (0) | 2021.08.15 |
[Modern C++][C++11] nullptr (0) | 2021.05.11 |
[C++] Class 공부 & instantiation (+ Struct) (0) | 2021.03.24 |
[Modern C++][C++11] Rvalue Reference and move semantics (0) | 2021.02.13 |