c++ vector.emplace_back()
std::vector::emplace_back
지원 버전
C++ 11
클래스
std::vector
함수
template<class.. Args>
void emplace_back(Args&&... args);
※ 가변인자를 받는다는 것이 특징이다.
설명
emplace_back은 vector의 마지막 요소 뒤에 추가해주는 함수이다. 이 함수는 두가지 특징을 가진다.
- 생성자를 위한 파라미터들을 직접 받는다.
=> 생성자 파라미터 순서대로 넣어줘야 한다. - vector 내부에서 객체를 직접 생성한다.
=> vector 외부에서 객체관리가 필요 없다. - 함수 호출 수를 줄여서 성능을 높인다.
=> vector 외부에서 객체를 만들어서 넣으면 최종 2번 호출하지만, vector 내부에서 객체를 만들어서 넣으므로 최종 1번 호출한다.
emplace_back은 push_back과 함께 보면 이해를 도울 것으로 생각된다. (C++98의) push_back은 (C++ 11의) emplace_back과는 다르게 동작한다. push_back은 함수 밖에서 객체를 생성한 후 입력 파라미터값으로 넣어주면 push_back 함수 안에서는 객체의 이동생성자를 호출해서 동작한다. 반면에, emplace_back은 함수 밖에서 객체를 생성하지 않고 객체 생성에 필요한 값 자체를 입력 파라미터값으로 받고 있기 때문에 emplace_back 함수안에서 객체의 이동생성자 한번만 호출하면 되는 것이다.
예제
아래 코드는 vector의 요소값을 emplace_back과 push_back를 사용해서 넣었을 때, 생성자가 몇 번 호출되는지를 보려는 것이다. emplace_back는 vector의 함수 중 하나로 사용법은 어렵지 않기 때문에, emplace_back이 어떤 특징이 있는지 이해하는 것을 목적으로 작성했다. 아래 예제의 각 함수를 호출했을 때 아래 순서로 호출된다. (참고로, 코드가 길어서 소멸자는 사용하지 않았다.)
- vector.emplace_back()
1. constructor 호출 (=생성)
2. move constructor 호출 (=생성)
3. move destructor 호출 (=파괴)
4. destructor 호출 (=파괴)
- vector.push_back()
1. constructor 호출 (=생성)
2. destructor 호출 (=파괴)
joker.hpp
#include <iostream>
#include <string>
using namespace std;
class Joker
{
private:
int _a;
string _b;
public:
// constructor
Joker(const int a, const string& b)
: _a(a)
, _b(b)
{
cout << _a << " " << _b << " at constructr" << endl;
}
// move constructor
Joker(Joker&& jk)
: _a(jk._a)
, _b(jk._b)
{
cout << _a << " " << _b << " at move constructor" << endl;
}
~Joker()
{
cout << _a << " " << _b << " at destructor" << endl;
}
};
main.cpp
#include <vector>
#include "joker.hpp"
using namespace std;
void emplace_back_test() {
vector<Joker> v;
// constructor 호출
v.emplace_back(47, "emplace_back");
}
void push_back_test() {
vector<Joker> v;
// constructor & move constructor 호출
v.push_back(Joker(23, "push_back"));
}
int main()
{
emplace_back_test();
push_back_test();
return 0;
}
실행결과
47 emplace_back at constructr
47 emplace_back at destructor
23 push_back at constructr
23 push_back at move constructor
23 push_back at destructor
23 push_back at destructor