move_if_noexcept — std::move_if_noexcept

move_if_noexcept — std::move_if_noexcept

std::move_if_noexcept이동이 예외를 던지지 않으면 rvalue 참조를, 그렇지 않으면(이동이 던질 수 있으면) lvalue 참조를 반환하는 함수예요. C++11에서 도입됐어요. <utility> 헤더에 있어요.

예외 안전한 이동/복사 선택을 돕는 도구예요.

출처: cppreference

본문

// <utility> 헤더, C++11 (C++14부터 constexpr)
template< class T >
/* see below */ move_if_noexcept( T& x ) noexcept;

x를 rvalue로 캐스팅할지 여부를 이동 생성자의 noexcept 여부로 결정해요.

  • 이동이 noexcept이면 → rvalue 참조 (이동).
  • 이동이 예외를 던질 수 있으면 → 복사가 안전하도록 lvalue로 둠.

사용 예

#include <utility>
#include <vector>

struct Movable {
    Movable(Movable&&) noexcept {}
};

struct ThrowingMove {
    ThrowingMove(ThrowingMove&&) {}   // noexcept 아님 — 던질 수 있음
};

// noexcept면 이동, 아니면 복사
auto r1 = std::move_if_noexcept(Movable{});
auto r2 = std::move_if_noexcept(ThrowingMove{});

왜 필요한가

표준 컨테이너가 재할당(reallocation) 시 예외 안전성을 보장하기 위해 사용해요. 이동이 던질 수 있으면 복사를 선택해 예외 발생 시 원래 상태를 유지해요.

// vector 재할당에서 이동이 noexcept면 이동, 아니면 복사
std::move_if_noexcept(*old_iter);

특징

  • 반환 타입은 T&& 또는 T& — 타입 특질(std::is_nothrow_move_constructible)에 따라 결정.
  • 표준 컨테이너 내부에서 예외 안전성 확보에 사용.

std::move_if_noexcept는 "이동해도 안전한가"를 고려해 이동/복사를 자동 선택하는 예외 안전 도구예요. 컨테이너 내부 구현에 핵심적이에요.

더 알아보기 (Learn more)

cppreference