본문 바로가기
STL

[STL] std::vector push_back과 emplace_back 차이점

728x90
반응형

push_back과 emplace_back의 차이점은?

vector 뒤에 객체를 삽입하여 줄 때 사용하는 함수는 push_back과 emplace_back이 있습니다. 두 함수를 모두 사용해보면 결과상으로는 큰차이가 없어 보이는데 내부적으로는 조금 다르게 작동합니다. 

 

#include <iostream>
#include <vector>

using namespace std;

class Object {
public:
	int num;
	Object(const int _num) : num(_num) { cout << "일반 생성자 호출" << endl; }
	Object(const Object& rhs) : num(rhs.num) { cout << "복사 생성자 호출" << endl; }
	Object(const Object&& rhs) noexcept : num(std::move(rhs.num)) { cout << "이동 생성자 호출" << endl; }
	~Object() { cout << "소멸자 호출" << endl; }
};

void EmplaceBack()
{
	vector<Object> vObjects;

	cout << "emplace_back" << endl;
	vObjects.emplace_back(3);
}

void PushBack()
{
	vector<Object> vObjects;

	cout << "push_back" << endl;
	vObjects.push_back(Object(3));
}

int main()
{
	EmplaceBack();
	cout << endl;
	PushBack();

	return 0;
}

push_back같은 경우에는 임시객체를 생성해줘서 넘겨줘야합니다. 그러면 push_back 내부에서 vector에 삽입될 새로운 객체를 생성해준 다음에 넘겨받은 임시객체의 정보를 새로운객체에 넘겨주고 임시객체는 소멸됩니다. push_back은 불필요한 생성을 한번 더 하기 때문에 이 단점을 보완하기 위해 나온것이 바로 emplace_back입니다.

 

emplace_back에 경우에는 이러한 push_back의 단점을 보완한 방식입니다. 객체의 정보를 넘겨줄때 임시객체를 생성하여 넘겨주는것이 아니라 생성에 필요한 매개변수만을 넘겨주고 함수내부에서 vector에 넣을 객체를 한번만 생성해주고 끝나기 때문에 push_back보다 효율적입니다.

 

push_back과 emplace_back 둘 다 존재 하는 이유는?

위에 내용만 볼때는 emplace_back이 push_back의 완벽한 상위호환같습니다. 하지만 진짜로 완벽한 상위호환이였으면 push_back은 진작에 사라졌겠죠. push_back이 emplace_back보다 유용할때도 있습니다.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector<vector<int>> arr;

	arr.push_back({ 0, 1, 2, 3 });

	for (int i = 0;i < arr[0].size();i++)
		cout << arr[0][i] << " ";
	cout << endl;
    
	return 0;
}

이렇듯 push_back은 객체를 통째로 넘겨주기 때문에 이렇게 배열째로 삽입이 가능한 반면에

 

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector<vector<int>> arr;

	arr.emplace_back({ 0, 1, 2, 3 }); // Error

	return 0;
}

emplace_back은 컴파일 과정에서 에러를 출력해냅니다.

반응형

'STL' 카테고리의 다른 글

[STL] 자료구조 원리와 시간 복잡도  (0) 2023.05.10
[STL] Vector배열에서 at()과 [] 접근의 차이점  (0) 2023.02.18