utility_move_if_noexcept

utility_move_if_noexcept (예외 안전 이동/복사 선택)

std::move_if_noexcept는 인자의 이동 생성자가 예외를 던지지 않거나 복사 생성자가 없는 경우(이동 전용 타입)에는 인자에 대한 rvalue 참조를 얻고, 그렇지 않으면 lvalue 참조를 얻는 함수예요. 이동 의미론과 강한 예외 보장을 결합하기 위해 주로 사용해요.

출처: cppreference

본문

<utility> 헤더에 정의됨
template < class T > /* see below */ move_if_noexcept ( T & x ) noexcept ; (since C++11) (constexpr since C++14)

std::move_if_noexcept는 인자의 이동 생성자가 예외를 던지지 않거나 복사 생성자가 없는 경우(이동 전용 타입)에는 인자에 대한 rvalue 참조를 얻고, 그렇지 않으면 lvalue 참조를 얻어요. 이 함수는 이동 의미론과 강한 예외 보장을 결합하기 위해 주로 사용돼요.

std::move_if_noexcept의 반환 타입은 다음과 같아요.

  • std::is_nothrow_move_constructible<T>::value가 true이거나 !std::is_copy_constructible<T>::value가 true라면 T&&예요.
  • 그렇지 않으면 const T&예요.

매개변수

x - 이동하거나 복사할 객체

반환값

예외 보장에 따라 std::move(x) 또는 x를 반환해요.

복잡도

상수 시간이에요.

참고

이 함수는 예를 들어 std::vector::resize에서 사용돼요. resize는 새 저장 공간을 할당한 다음 기존 저장 공간에서 새 저장 공간으로 요소를 이동하거나 복사해야 할 수 있어요. 이 작업 중 예외가 발생하면 std::vector::resize는 지금까지 수행한 모든 작업을 되돌려요. 이는 std::move_if_noexcept를 사용하여 이동 생성을 사용할지 복사 생성을 사용할지 결정한 경우에만 가능해요. (복사 생성자를 사용할 수 없는 경우에는 어차피 이동 생성자를 사용하며, 강한 예외 보장이 적용되지 않을 수 있어요.)

예제

#include <iostream>
#include <utility>

struct Bad
{
    Bad() {}
    Bad(Bad&&) // may throw
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // may throw as well
    {
        std::cout << "Throwing copy constructor called\n";
    }
};

struct Good
{
    Good() {}
    Good(Good&&) noexcept // will NOT throw
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // will NOT throw
    {
        std::cout << "Non-throwing copy constructor called\n";
    }
};

int main()
{
    Good g;
    Bad b;
    [[maybe_unused]] Good g2 = std::move_if_noexcept(g);
    [[maybe_unused]] Bad b2 = std::move_if_noexcept(b);
}

출력:

Non-throwing move constructor called
Throwing copy constructor called

같이 보기

forward (C++11) 함수 인자를 전달하고 타입 템플릿 인자를 사용하여 값 카테고리를 보존해요 (함수 템플릿) [edit]
move (C++11) 인자를 xvalue로 변환해요 (함수 템플릿) [edit]

더 알아보기 (Learn more)

cppreference