💡 퀵 접속: cpp.kr/move_backward

move_backward

C++ 표준 라이브러리의 알고리즘으로, 주어진 범위의 요소들을 역방향으로 다른 범위로 이동합니다. 원본 범위의 요소들은 이동 후에는 유효하지 않은 상태가 됩니다. 역방향 이동은 원본과 대상 범위가 겹칠 때 유용하며, 이동 연산은 복사보다 효율적입니다.

기본 사용법

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

int main() {
    std::vector<std::string> source = {"Hello", "World", "C++"};
    std::vector<std::string> destination(3);
    
    // source의 문자열들을 destination으로 역방향 이동
    std::move_backward(source.begin(), source.end(), destination.end());
    
    // 결과 출력
    std::cout << "원본 (이동 후): ";
    for (const auto& s : source) {
        std::cout << (s.empty() ? "empty" : s) << " ";
    }
    std::cout << std::endl;
    
    std::cout << "대상: ";
    for (const auto& s : destination) {
        std::cout << s << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

실행 결과:

원본 (이동 후): empty empty empty
대상: Hello World C++

겹치는 범위 이동

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

int main() {
    std::vector<std::string> strings = {"A", "B", "C", "D", "E", "F"};
    
    // 중간 부분을 오른쪽으로 한 칸 이동
    std::move_backward(strings.begin() + 2, strings.begin() + 4, strings.begin() + 5);
    
    std::cout << "이동 후: ";
    for (const auto& s : strings) {
        std::cout << (s.empty() ? "empty" : s) << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

실행 결과:

이동 후: A B empty C D F

사용자 정의 타입 이동

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

class Resource {
    std::string name;
    int* data;
public:
    Resource(const std::string& n, int size) : name(n), data(new int[size]) {
        std::cout << name << " 생성됨" << std::endl;
    }
    
    // 이동 생성자
    Resource(Resource&& other) noexcept : name(std::move(other.name)), data(other.data) {
        other.data = nullptr;
        std::cout << name << " 이동됨" << std::endl;
    }
    
    // 이동 대입 연산자
    Resource& operator=(Resource&& other) noexcept {
        if (this != &other) {
            delete[] data;
            name = std::move(other.name);
            data = other.data;
            other.data = nullptr;
            std::cout << name << " 이동 대입됨" << std::endl;
        }
        return *this;
    }
    
    ~Resource() {
        delete[] data;
        std::cout << name << " 소멸됨" << std::endl;
    }
};

int main() {
    std::vector<Resource> source;
    source.emplace_back("Resource1", 10);
    source.emplace_back("Resource2", 20);
    source.emplace_back("Resource3", 30);
    
    std::vector<Resource> destination(3);
    
    // source의 Resource 객체들을 destination으로 역방향 이동
    std::move_backward(source.begin(), source.end(), destination.end());
    
    return 0;
}

실행 결과:

Resource1 생성됨
Resource2 생성됨
Resource3 생성됨
Resource1 이동됨
Resource2 이동됨
Resource3 이동됨
Resource1 소멸됨
Resource2 소멸됨
Resource3 소멸됨

참고사항

  • move_backward는 algorithm 헤더에 정의되어 있습니다.
  • 원본 범위의 요소들은 이동 후에는 유효하지 않은 상태가 됩니다.
  • 시간 복잡도는 O(n)입니다 (n은 범위의 크기).
  • 대상 범위는 원본 범위와 크기가 같거나 더 커야 합니다.
  • move와 달리 역방향으로 이동하므로, 원본과 대상 범위가 겹칠 때 안전하게 사용할 수 있습니다.
  • 대상 범위의 끝 위치를 지정해야 합니다 (move는 시작 위치를 지정).
  • 이동 가능한 타입(moveable type)에 대해서만 사용할 수 있습니다.
  • 이동 후에는 원본 객체를 사용하지 않아야 합니다.
  • 리소스 관리가 필요한 객체를 다룰 때 특히 유용합니다.
함수 설명
move_backward(first, last, d_last) first부터 last까지의 범위의 요소들을 d_last부터 역방향으로 이동