# std::ranges::in_out_result

< cpp‎ | algorithm‎ | ranges

定义于头文件 `<algorithm>` |  |
template <class I, class O> struct in_out_result; |  | (C++20 起)

`ranges::in_out_result` 是类模板，提供存储二个迭代器为单个单元的方式。

此类模板无基类或显示如下的声明的数据成员，从而它适合用于结果化绑定。

此类模板的所有特殊成员函数均为隐式声明，这使得特化为聚合类，并传播数据成员上的操作的平凡性、潜在抛出性及 constexpr 性质。

### 模板形参

I, O | - | `ranges::in_out_result` 所存储的对象类型

### 数据成员

## std::ranges::in_out_result::in

[[no_unique_address]] I in; |  |

值（假定为迭代器）

## std::ranges::in_out_result::out

[[no_unique_address]] O out; |  |

值（假定为迭代器）

### 成员函数

## std::ranges::in_out_result::operator in_out_result<I2, O2>

template<class I2, class O2> requires std::convertible_to<const I&, I2> && std::convertible_to<const O&, O2> constexpr operator in_out_result<I2, O2>() const &; | (1) |
template<class I2, class O2> requires std::convertible_to<I, I2> && std::convertible_to<O, O2> constexpr operator in_out_result<I2, O2>() &&; | (2) |

通过从 *this 的每个数据成员构造结果的对应成员，转换 *this 为结果。

1) 等价于 return {in, out}; 。
2) 等价于 return {std::move(in), std::move(out)}; 。

### 标准库

下列标准库函数以 `ranges::in_out_result` 为返回类型：

##### 算法函数
ranges::copy ranges::copy_if (C++20)(C++20) | 将某一范围的元素复制到一个新的位置 (niebloid)
ranges::copy_n (C++20) | 将一定数目的元素复制到一个新的位置 (niebloid)
ranges::copy_backward (C++20) | 按从后往前的顺序复制一个范围内的元素 (niebloid)
ranges::move (C++20) | 将某一范围的元素移动到一个新的位置 (niebloid)
ranges::move_backword (C++20) | 按从后往前的顺序移动某一范围的元素到新的位置 (niebloid)
ranges::transform (C++20) | 将一个函数应用于某一范围的各个元素 (niebloid)
ranges::replace_copy ranges::replace_copy_if (C++20)(C++20) | 复制一个范围内的元素，并将满足特定判别标准的元素替换为另一个值 (niebloid)
ranges::remove_copy ranges::remove_copy_if (C++20)(C++20) | 复制一个范围的元素，忽略满足特定判别标准的元素 (niebloid)
ranges::unique_copy (C++20) | 创建某范围的不含连续重复元素的副本 (niebloid)
ranges::revserse_copy (C++20) | 创建一个范围的逆向副本 (niebloid)
ranges::rotate_copy (C++20) | 复制并旋转元素范围 (niebloid)
ranges::partial_sort_copy (C++20) | 对范围内的元素进行复制并部分排序 (niebloid)
ranges::set_difference (C++20) | 计算两个集合的差集 (niebloid)
##### 未初始化内存函数
ranges::uninitialized_copy (C++20) | 复制元素范围到未初始化的内存区域 (niebloid)
ranges::uninitialized_copy_n (C++20) | 复制一定量元素到未初始化的内存区域 (niebloid)
ranges::uninitialized_move (C++20) | 移动对象范围到未初始化的内存区域 (niebloid)
ranges::uninitialized_move_n (C++20) | 移动一定量对象到未初始化的内存区域 (niebloid)

### 概要

    namespace std::ranges {
        template<class I, class O>
        struct in_out_result {
            [[no_unique_address]] I in;
            [[no_unique_address]] O out;

            template<class I2, class O2>
            requires std::convertible_to<const I&, I2> && std::convertible_to<const O&, O2>
            constexpr operator in_out_result<I2, O2>() const & {
                return {in, out};
            }

            template<class I2, class O2>
            requires std::convertible_to<I, I2> && std::convertible_to<O, O2>
            constexpr operator in_out_result<I2, O2>() && {
                return {std::move(in), std::move(out)};
            }
        };
    }

### 注解

每个使用此返回类型族的标准库算法声明新的别名类型，例如 using merge_result = in_in_out_result<I1, I2, O>; 。

这些别名族的名称由添加 "`_result`" 到算法名组成。故 `std::ranges::merge` 的返回类型能命名为 `std::ranges::merge_result` 。

不同于 std::pair 与 std::tuple ，此类模板的拥有名字有意义的数据成员。

### 示例

    #include <algorithm>
    #include <array>
    #include <cctype>
    #include <iostream>
    #include <ranges>

    int main()
    {
        constexpr char in[] = "transform" "\n";
        std::array<char, sizeof(in)> out;

        const auto result = std::ranges::transform(in, out.begin(),
            [](char c) { return std::toupper(c); });

        auto print = [](char c) { std::cout << c; };
        std::ranges::for_each(std::cbegin(in), result.in, print);
        std::ranges::for_each(out.cbegin(), result.out, print);
    }

输出：

    transform
    TRANSFORM

### 参阅

pair | 实现二元组，即一对值 (类模板)
tuple (C++11) | 实现固定大小的容器，它保有类型可以相异的元素 (类模板)