# std::is_assignable, std::is_trivially_assignable, std::is_nothrow_assignable

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template< class T, class U > struct is_assignable; | (1) | (C++11 起)
template< class T, class U > struct is_trivially_assignable; | (2) | (C++11 起)
template< class T, class U > struct is_nothrow_assignable; | (3) | (C++11 起)

1) 若表达式 std::declval<T>() = std::declval<U>() 在不求值语境为良态，则提供等于 true 的成员常量 `value` 。否则， `value` 为 false 。如同从与不关联到任一方的语境进行访问检查。
2) 同 (1) ，但赋值表达式的求值将不调用任何非平凡的操作。为此检查的目的，对 std::declval 的调用被认为是平凡，且不是 std::declval 的 odr 使用。
3) 同 (1) ，但复制表达式的求值将不调用任何不是 noexcept 的操作。

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

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

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

### 辅助变量模板

template< class T, class U > inline constexpr bool is_assignable_v = is_assignable<T, U>::value; |  | (C++17 起)
template< class T, class U > inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value; |  | (C++17 起)
template< class T, class U > inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value; |  | (C++17 起)

## 继承自 std::integral_constant

### 成员常量

value [静态] | 若 `T` 可从 `U` 赋值则为 true ，否则为 false (公开静态成员常量)

### 成员函数

operator bool | 转换对象为 bool ，返回 `value` (公开成员函数)
operator() (C++14) | 返回 `value` (公开成员函数)

### 成员类型

类型 | 定义
`value_type` | `bool`
`type` | std::integral_constant<bool, value>

### 注意

此特性不检查任何赋值表达式立即语境之外的任何事物：若 `T` 或 `U` 的使用会触发模板特化，生成隐式定义的成员函数，而它们拥有错误，则实际赋值可能无法编译，即使 `std::is_assignable<T,U>::value` 通过编译并求值为 `true` 。

### 示例

    #include <iostream>
    #include <string>
    #include <type_traits>
    struct Ex1 { int n; };
    int main() {
        std::cout << std::boolalpha
                  << "int is assignable from int? "
                  << std::is_assignable<int, int>::value << '\n' // 1 = 1; wouldn't compile
                  << "int& is assignable from int? "
                  << std::is_assignable<int&, int>::value << '\n' // int a; a = 1; works
                  << "int is assignable from double? "
                  << std::is_assignable<int, double>::value << '\n'
                  << "int& is nothrow assignable from double? "
                  << std::is_nothrow_assignable<int&, double>::value << '\n'
                  << "string is assignable from double? "
                  << std::is_assignable<std::string, double>::value << '\n'
                  << "Ex1& is trivially assignable from const Ex1&? "
                  << std::is_trivially_assignable<Ex1&, const Ex1&>::value << '\n';
    }

输出：

    int is assignable from int? false
    int& is assignable from int? true
    int is assignable from double? false
    int& is nothrow assignable from double? true
    string is assignable from double? true
    Ex1& is trivially assignable from const Ex1&? true

### 参阅

is_copy_assignable is_trivially_copy_assignable is_nothrow_copy_assignable (C++11)(C++11)(C++11) | 检查类型是否拥有复制赋值运算符 (类模板)
is_move_assignable is_trivially_move_assignable is_nothrow_move_assignable (C++11)(C++11)(C++11) | 检查类型是否有拥有移动赋值运算符 (类模板)