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는 "이동해도 안전한가"를 고려해 이동/복사를 자동 선택하는 예외 안전 도구예요. 컨테이너 내부 구현에 핵심적이에요.