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

C++ 기본 타입은 왜 std::move()로 이동되지 않는가?

by bantomak 2025. 12. 20.
반응형

기본 타입(Primitive Type) 이동시키기

우선, 기본 타입인 int를 복사하고 이동시키는 코드를 작성해 보자.

std::vector<int> vec;

int a = 1;
vec.push_back(a); // copy
std::cout << "a :" << a << endl; 

vec.emplace_back(std::move(a)); // copy
std::cout << "a :" << a << endl;

결과를 보면 std::move()를 사용했지만 이동 대입 연산자가 동작하지 않았다. 기본 타입의 경우는 할수 있는 게 복사뿐이라서 std::move()를 사용하더라도 이동이 일어나지 않는다. 복사가 일어난다.

기본 타입(Primitive Type)은 왜 이동을 지원하지 않는가?

기본 타입은 '자원'을 소유하지 않는다. 이동과 복사가 완전히 같은 의미로 동작한다. 따라서 이동을 별도로 정의할 이유가 없다.

  • 값 그 자체
  • 힙 자원 없음
  • 소유권 개념 없음
  • 내부 상태 없음

기본 타입(Primitive Type)은 언제나 유효하다!

int a = 10;
int b = std::move(a);

a를 조회해 보면 std::move()로 이동시켰지만 여전히 10인걸 알 수 있다. 기본 타입은 언제나 유효한 값을 지닌다. std::move()의 철학은 '소유권의 이전'이다. 즉, 소유권이라는 개념이 없는 기본 타입에서는 동작하지 않는다.

사용자 정의타입 std::string 이동시키기

사용자 정의타입인 std::string는 std::move()로 이동(move)되기 때문에 std::move() 이후 값을 출력해 보면 빈값으로 출력된다.

정상적으로 소유권이 이전된 것이다.

std::vector<std::string> vec;

std::string s = "hello";
vec.push_back(s); // copy
std::cout << "s :" << s << endl;

vec.emplace_back(std::move(s)); // move
std::cout << "s :" << s << endl;

정리하자면

  • std::move()는 소유권을 이전시킨다.
  • 기본 타입은 소유권이라는 게 존재하지 않기 때문에 의미가 없다.
  • 따라서 이동시에도 복사가 일어난다.

추가 질문: std::move() 이후 원본은 무조건 비워지는가?

C++ 표준에서 "move 이후 원본은 반드시 비워져야 한다"와 같은 규칙은 존재하지 않는다.

규칙은 오직 하나: moved-form 객체는 "유효하지만 어떤 값일지는 모르는 상태"여야 한다는 것이다. 

(valid but unspecified state)

댓글