본문 바로가기
프로그래밍/C++

이동(move)이 더 효율적인데 emplace_back()은 왜 복사하는가?

by bantomak 2025. 12. 6.
반응형

이동(move)이 더 효율적인데 emplace_back()은 왜 복사(copy)하는가?

emplace_back()이 '이동(move)'이 아닌 '복사(copy)'하는 이유는, 프로그래머가 l-value 변수를 전달하면 해당 변수를 앞으로 또 사용할 수도 있다고 컴파일러는 가정해야만 하기 때문이다.

 

이름 있는 변수(l-value)는 다음에 또 사용할지도 모르는 소중한 변수이기 때문에 emplace_back()의 인자로 들어오면 이동하지 않고 복사를 수행합니다. 만약 이동시킨다면 해당 변수 data는 빈 껍데기만 남아서 다른 곳에서 사용이 불가능하다.

// l-value 생성
MyData data;
data.ID = 1;
data.Name = "kane";
data.Address = "ganam-gu";

std::vector<MyData> myVec;
myVec.emplace_back(data); // copy
myVec.emplace_back(std::move(data)); // move
  • emplace_back()은 복사(copy)와 이동(move)을 모두 지원한다.
  • std::move()를 사용하면 l-value를 이동으로 지정할 수 있다.

emplace_back()의 진가

emplace_back()에 인자로 l-value가 들어오면 복사가 진행된다. emplace_back()의 진가는 r-value 즉, 객체를 미리 만들지 않고 생성자에서 인자를 넘겨줄 때 발휘된다.

// 1. push_back: 임시 객체를 만들고 -> 벡터로 '이동'시킴
m_vec.push_back(ArenaRank(1, 100, "PlayerA")); // 1. 임시 객체 생성, 2. 이동

// 2. emplace_back: 벡터 안에서 '바로' 생성함
m_vec.emplace_back(1, 100, "PlayerA"); // 1. 바로 생성 (더 효율적)

정리하자면

  • emplace_back()은 복사(copy)이동(move)을 둘 다 지원한다.
  • 이름 있는 객체(l-value) 인자가 들어오면 복사, 이름 없는 임시 객체(r-value) 인자가 들어오면 이동을 수행한다.
  • push_back도 복사(copy)와 이동을 둘 다 지원한다.
  • emplace_back은 바로 생성(in-place construction)을 지원하지만 push_back은 지원하지 않음

emplace_back()를 사용하는 방법의 종류 대해서 알아보자면,

  • emplace_back(l-value) 복사 생성자로 복사 (별도의 객체를 생성하므로 안전)
  • emplace_back(std::move(l-value)) (이동해도 된다고 허락함) 이동 생성자로 이동
  • emplace_back(r-value{...})  이동 생성자로 이동
  • emplace_back({...})  바로 생성(in-place construction)

emplace_back()은 push_back과는 다르게 바로 생성이 가능하므로 복사나 이동없이 추가가 가능하다.

더 생각해보기

왜 C++ Core Guidelines가 무조건 emplace_back()을 권장하지 않는가?

댓글