# std::is_move_constructible, std::is_trivially_move_constructible, std::is_nothrow_move_constructible

< cpp‎ | types

定义于头文件 `<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 起)

1) 若 `T` 不是可引用类型（即可为 cv 限定的 void 或带 cv-qualifier-seq 或 ref-qualifier 的函数类型），则提供等于 false 的成员常量 `value` 。否则，提供等于 std::is_constructible<T, T&&>::value 的成员常量 `value`。
2) 同 (1) ，但使用 std::is_trivially_constructible<T, T&&> 。
3) 同 (1) ，但使用 std::is_nothrow_constructible<T, T&&> 。

`T` 应为完整类型、（可为 cv 限定的） void ，或未知边界数组。否则行为未定义。

若上述模板的实例化直接或间接地依赖于不完整类型，并且如果假如使该类型完整，实例化就会产生不同的结果，则行为未定义。

添加此页面上描述的任何模板的特化的程序行为未定义。

### 辅助变量模板

template< class T > inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value; |  | (C++17 起)
template< class T > inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value; |  | (C++17 起)
template< class T > inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value; |  | (C++17 起)

## 继承自 std::integral_constant

### 成员常量

value [静态] | 若 `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 ，因为否则它们就不可用于任何提供强异常保证的代码中。

多数实现中， `is_nothrow_move_constructible` 亦检查析构函数是否抛出，因为它等效于 noexcept(T(arg)) 。同样的情况应用于 `is_trivially_move_constructible` ，它在这些实现中亦要求析构函数为平凡： GCC 漏洞 51452 、 LWG 问题 2116。

### 示例

    #include <iostream>
    #include <type_traits>

    struct Ex1 {
        std::string str; // 成员拥有非平凡而不抛出的移动构造函数
    };
    struct Ex2 {
        int n;
        Ex2(Ex2&&) = default; // 平凡且不抛出
    };
    struct NoMove {
        // 避免默认移动构造函数的隐式声明
        // 然而，该类仍为可移动构造因为复制构造函数能绑定到右值参数
        NoMove(const NoMove&) {}
    };

    int main() {
        std::cout << std::boolalpha << "Ex1 is move-constructible? "
                  << std::is_move_constructible<Ex1>::value << '\n'
                  << "Ex1 is trivially move-constructible? "
                  << std::is_trivially_move_constructible<Ex1>::value << '\n'
                  << "Ex1 is nothrow move-constructible? "
                  << std::is_nothrow_move_constructible<Ex1>::value << '\n'
                  << "Ex2 is trivially move-constructible? "
                  << std::is_trivially_move_constructible<Ex2>::value << '\n'
                  << "Ex2 is nothrow move-constructible? "
                  << std::is_nothrow_move_constructible<Ex2>::value << '\n';

        std::cout << std::boolalpha
                  << "NoMove is move-constructible? "
                  << std::is_move_constructible<NoMove>::value << '\n'
                  << "NoMove is nothrow move-constructible? "
                  << std::is_nothrow_move_constructible<NoMove>::value << '\n';
    }

输出：

    Ex1 is move-constructible? true
    Ex1 is trivially move-constructible? false
    Ex1 is nothrow move-constructible? true
    Ex2 is trivially move-constructible? true
    Ex2 is nothrow move-constructible? true
    NoMove is move-constructible? true
    NoMove is nothrow move-constructible? false

### 参阅

is_constructible is_trivially_constructible is_nothrow_constructible (C++11)(C++11)(C++11) | 检查类型是否带有针对特定实参的构造函数 (类模板)
is_default_constructible is_trivially_default_constructible is_nothrow_default_constructible (C++11)(C++11)(C++11) | 检查类型是否有默认构造函数 (类模板)
is_copy_constructible is_trivially_copy_constructible is_nothrow_copy_constructible (C++11)(C++11)(C++11) | 检查类型是否拥有复制构造函数 (类模板)
move_if_noexcept (C++11) | 若移动构造函数不抛出则获得右值引用 (函数模板)