Programming Language/C++

[Modern C++] std::move, std::forward

lumana 2024. 6. 30. 19:26

추후 내용 보충. 예정

 

std::movestd::forward는 모두 C++11 이후부터 도입된 유틸리티 함수들로, 둘 다 값의 전달 방식을 조절하는 데 사용됩니다. 그러나 각각의 역할과 사용하는 상황이 다르므로, 이 둘을 정확히 이해하는 것이 중요합니다.

std::move

역할: std::move는 주어진 인자를 "이동"할 수 있도록 하는 역할을 합니다. 이동(move)이란 객체의 자원(메모리 등)을 다른 객체로 옮기는 것을 말하며, 복사보다 효율적인 자원 관리를 가능하게 합니다.

사용 방법: std::move는 주로 객체를 이동할 때 사용됩니다. 이 함수는 주어진 인자를 rvalue reference로 변환하여, 이동 연산자(move constructor 또는 move assignment operator)를 호출할 수 있게 합니다.

예시:

#include <utility>
#include <vector>

int main() {
    std::vector<int> v1 = {1, 2, 3};
    std::vector<int> v2 = std::move(v1); // v1의 자원을 v2로 이동

    // 이제 v1은 비어 있음

    return 0;
}

std::forward

역할: std::forward는 주어진 인자를 "전달"할 때 사용됩니다. 전달(forward)이란 함수 템플릿의 매개변수를 다른 함수에 그대로 전달하는 것을 의미합니다. 이는 템플릿 매개변수의 형태를 유지하면서 완벽한 전달(forwarding)을 가능하게 합니다.

사용 방법: std::forward는 주로 forwarding reference (universal reference)를 사용할 때 유용합니다. forwarding reference는 T&& 형태의 매개변수로, 템플릿 매개변수의 형태를 유지하면서 왼값(lvalue)와 오른값(rvalue) 모두를 받을 수 있습니다.

예시:

#include <utility>

// 예시 함수 템플릿
template <typename T>
void wrapper(T&& arg) {
    some_function(std::forward<T>(arg)); // arg를 그대로 전달
}

int main() {
    int x = 42;
    wrapper(x); // 왼값 전달
    wrapper(123); // 오른값 전달

    return 0;
}

차이점 정리

  • std::move는 주로 이동 연산을 활성화시키기 위해 사용되며, 객체의 자원을 다른 객체로 이동시킵니다.
  • std::forward는 주로 forwarding reference를 다룰 때 사용되며, 완벽한 전달(forwarding)을 통해 함수 템플릿 매개변수의 형태를 유지하면서 인자를 전달합니다.

이 두 함수는 모두 템플릿 프로그래밍과 제네릭 프로그래밍에서 매우 중요한 역할을 합니다. 특히 이동 시맨틱과 퍼펙트 포워딩(perfect forwarding)에서 중요한 개념들입니다.