# C++ 具名要求：值可交换 (ValueSwappable)

< cpp‎ | named req

此类型的两个对象可以解引用，且在 std::swap 和用户定义 swap() 均可见的语境中，其结果值可以用无限定的函数调用 swap() 进行交换。

### 要求

以下情况下，类型 T 为值可交换 (ValueSwappable) :

1. 类型 `T` 满足老式迭代器 (LegacyIterator) 要求
2. 对任何 `T` 类型的可解引用对象 `x`（即并非尾迭代器的值），`*x` 满足可交换 (Swappable) 要求。

许多标准库函数均期待其实参满足值可交换 (ValueSwappable) ，这意味着凡在标准库进行交换时，它都使用 using std::swap; swap(*iter1, *iter2); 的等价物。

### 示例

    #include <iostream>
    #include <vector>

    class IntVector {
        std::vector<int> v;
        IntVector& operator=(IntVector); // 不可赋值
     public:
        void swap(IntVector& other) {
            v.swap(other.v);
        }
    };
    void swap(IntVector& v1, IntVector& v2) {
        v1.swap(v2);
    }

    int main()
    {
        IntVector v1, v2;    // IntVector 为可交换 (Swappable)，但非可移动赋值 (MoveAssignable)
        IntVector* p1 = &v1;
        IntVector* p2 = &v2; // IntVector* 为值可交换 (ValueSwappable)
        std::iter_swap(p1, p2); // OK：iter_swap 要求值可交换 (ValueSwappable)
    //  std::swap(v1, v2); // 编译器错误！std::swap 要求可移动赋值 (MoveAssignable)
    }

### 参阅

indirectly_swappable (C++20) | 指定能交换两个 `indirectly_readable` 类型所引用的值 (概念)