types_is_move_constructible

types_is_move_constructible (이동 생성 가능 여부 판별)

<type_traits> 헤더에 정의된 std::is_move_constructible 계열 타입 특성은 어떤 타입이 이동 생성자(move constructor)로 생성될 수 있는지, 그 생성자가 사소한지(trivial), 예외를 던지지 않는지(nothrow)를 컴파일 타임에 검사해요. 이 템플릿들은 SFINAE나 static_assert와 함께 사용되어 타입의 이동 의미론을 조건부로 활성화하거나 검증하는 데 유용해요.

출처: cppreference

본문

정의

<type_traits> 헤더에 정의되어 있어요.

<type_traits> 헤더에 정의됨
template < class T > struct is_move_constructible ; (1) (C++11부터)
template < class T > struct is_trivially_move_constructible ; (2) (C++11부터)
template < class T > struct is_nothrow_move_constructible ; (3) (C++11부터)

만약 T가 완전한 타입(complete type)이 아니거나, (cv 한정을 포함한) void이거나, 경계를 알 수 없는 배열(array of unknown bound)이라면 동작은 정의되지 않아요. 또한 위 템플릿 중 하나의 인스턴스화가 불완전한 타입에 직간접적으로 의존하는데, 그 타입이 가상으로 완성되었을 때 결과가 달라질 수 있다면 동작은 정의되지 않아요. 이 페이지에 설명된 템플릿들에 대해 프로그램이 특수화를 추가하면 동작은 정의되지 않아요.

헬퍼 변수 템플릿

템플릿 버전
template < class T > constexpr bool is_move_constructible_v = is_move_constructible < T >:: value ; (C++17부터)
template < class T > constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible < T >:: value ; (C++17부터)
template < class T > constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible < T >:: value ; (C++17부터)

std::integral_constant에서 상속됨

멤버 상수

이름 설명
value [static] T가 이동 생성 가능하면 true, 아니면 false (공용 정적 멤버 상수)

멤버 함수

이름 설명
operator bool 객체를 bool로 변환하며 value를 반환해요 (공용 멤버 함수)
operator() (C++14) value를 반환해요 (공용 멤버 함수)

멤버 타입

타입 정의
value_type bool
type std :: integral_constant < bool , value >

가능한 구현

template < class T > struct is_move_constructible : std :: is_constructible < T , typename std :: add_rvalue_reference < T >:: type > {};
template < class T > struct is_trivially_move_constructible : std :: is_trivially_constructible < T , typename std :: add_rvalue_reference < T >:: type > {};
template < class T > struct is_nothrow_move_constructible : std :: is_nothrow_constructible < T , typename std :: add_rvalue_reference < T >:: type > {};

참고 사항

이동 생성자가 없지만 const T& 인수를 받는 복사 생성자가 있는 타입은 std::is_move_constructible 조건을 만족해요. 이동 생성자는 보통 noexcept로 선언되는데, 그렇지 않으면 강한 예외 보장(strong exception guarantee)을 제공하는 코드에서 사용할 수 없기 때문이에요. 많은 구현에서 std::is_nothrow_move_constructible은 사실상 noexcept(T(arg))이므로 소멸자가 예외를 던지는지도 확인해요. std::is_trivially_move_constructible도 마찬가지로, 이러한 구현에서는 소멸자가 사소한지도 요구해요 (GCC 버그 51452, LWG 이슈 2116).

예제

#include <string>
#include <type_traits>

struct Ex1
{
    std::string str; // member has a non-trivial but non-throwing move constructor
};
static_assert(std::is_move_constructible_v<Ex1>);
static_assert(!std::is_trivially_move_constructible_v<Ex1>);
static_assert(std::is_nothrow_move_constructible_v<Ex1>);

struct Ex2
{
    int n;
    Ex2(Ex2&&) = default; // trivial and non-throwing
};
static_assert(std::is_move_constructible_v<Ex2>);
static_assert(std::is_trivially_move_constructible_v<Ex2>);
static_assert(std::is_nothrow_move_constructible_v<Ex2>);

struct NoMove1
{
    // prevents implicit declaration of default move constructor;
    // however, the class is still move-constructible because its
    // copy constructor can bind to an rvalue argument
    NoMove1(const NoMove1&) {}
};
static_assert(std::is_move_constructible_v<NoMove1>);
static_assert(!std::is_trivially_move_constructible_v<NoMove1>);
static_assert(!std::is_nothrow_move_constructible_v<NoMove1>);

struct NoMove2
{
    // Not move-constructible since the lvalue reference
    // can't bind to the rvalue argument
    NoMove2(NoMove2&) {}
};
static_assert(!std::is_move_constructible_v<NoMove2>);
static_assert(!std::is_trivially_move_constructible_v<NoMove2>);
static_assert(!std::is_nothrow_move_constructible_v<NoMove2>);

int main() {}

결함 보고서

다음 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.

DR 적용 대상 발표된 동작 올바른 동작
LWG 2196 C++11 T&&를 형성할 수 없을 때 동작이 불명확했음 이 경우 생성되는 값은 false

같이 보기

템플릿/개념 설명
is_constructible, is_trivially_constructible, is_nothrow_constructible (C++11) 특정 인수에 대한 생성자가 있는지 검사해요 (클래스 템플릿)
is_default_constructible, is_trivially_default_constructible, is_nothrow_default_constructible (C++11) 기본 생성자가 있는지 검사해요 (클래스 템플릿)
is_copy_constructible, is_trivially_copy_constructible, is_nothrow_copy_constructible (C++11) 복사 생성자가 있는지 검사해요 (클래스 템플릿)
move_constructible (C++20) 어떤 타입의 객체가 이동 생성될 수 있음을 명시하는 개념
move (C++11) 인수를 xvalue로 변환해요 (함수 템플릿)
move_if_noexcept (C++11) 이동 생성자가 예외를 던지지 않으면 인수를 xvalue로 변환해요 (함수 템플릿)
is_move_constructible_type, is_trivially_move_constructible_type, is_nothrow_move_constructible_type (C++26) 반영된 타입이 rvalue 참조로부터 생성될 수 있는지 검사해요 (함수)

더 알아보기 (Learn more)

cppreference