# std::ranges::views::transform, std::ranges::transform_view

< cpp‎ | ranges

定义于头文件 `<ranges>` |  |
template< ranges::input_range V, std::copy_constructible F > requires ranges::view<V> && std::is_object_v<F> && std::regular_invocable<F&, ranges::range_reference_t<V>> && /* invoke_result_t<F&, range_reference_t<V>>& 是合法类型 */ class transform_view : public ranges::view_interface<transform_view<V, F>> | (1) | (C++20 起)
namespace views { inline constexpr /*unspecified*/ transform = /*unspecified*/; } | (2) | (C++20 起)

1) 表示底层序列应用变换函数到每个元素后的 `view` 的范围适配器。
2) 范围适配器对象。对每个适合的表达式 e 与 f ，表达式 views::transform(e, f) 表达式等价于 transform_view(e, f) 。

`transform_view` 分别在底层视图 V 实现 `random_access_range`、 `bidirectional_range`、 `forward_range`、 `input_range`、 `common_range` 与 `sized_range` 时实现同一概念。

### 表达式等价

表达式 e 表达式等价于表达式 f ，若 e 与 f 拥有相同效果，均为潜在抛出或均非潜在抛出（即 noexcept(e) == noexcept(f) ），且均为常量子表达式或均非常量子表达式。

### 成员函数

(构造函数) (C++20) | 构造 `transform_view` (公开成员函数)
base (C++20) | 返回底层（适配的）视图的副本 (公开成员函数)
begin (C++20) | 返回指向起始的迭代器 (公开成员函数)
end (C++20) | 返回指向末尾的迭代器或哨位 (公开成员函数)
size (C++20) | 返回元素数，只要底层（适配的）范围满足 `sized_range` (公开成员函数)
##### 继承自 std::ranges::view_interface
empty (C++20) | 返回视图是否为空。若视图满足 `forward_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
operator bool (C++20) | 返回派生视图是否为非空。若 ranges::empty 可应用于它则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
front (C++20) | 返回派生视图中的首元素。若视图满足 `forward_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
back (C++20) | 返回派生视图中的末元素。若视图满足 `bidirectional_range` 与 `common_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
operator[] (C++20) | 返回派生视图中的第 n 个元素。若视图满足 `random_access_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)

### 推导指引

### 嵌套类

iterator (C++20) | 迭代器类型 (仅用于阐释的成员类模板)
sentinel (C++20) | 哨位类型 (仅用于阐释的成员类模板)

### 示例

    #include <array>
    #include <cstdio>
    #include <ranges>
    #include <string>

    class Transcoder {
        static constexpr std::array r{
            0x02,-0x02,-0x42, 0x05, 0x04, 0x05, 0x04,-0x02,
            0x00,-0x0a, 0x06,-0x04, 0x00, 0x0c, 0x03,-0x06,
        };
        decltype(r.size()) p{}, q{};
    public:
        char operator() (int x) {
            ! (p|q)
            ? (99 == x ? x += r[p++]  : x -= r[q++])
            : (0 < p && p < r.size()) ? x += r[p++]
            : (0 < q && q < r.size()) ? x -= r[q++]
            : (0)
            ;
            return x;
        }
    };

    int main()
    {
        auto show = [](const char x) { std::putchar(x); };

        std::string in{ "cppreference.com\n" };
        std::ranges::for_each(in, show);

        std::string out;
        std::ranges::copy(
            std::ranges::views::transform(in, Transcoder{}),
            std::ranges::back_inserter(out));
        std::ranges::for_each(out, show);

        auto view = std::transform_view{ out, Transcoder{} };
        std::ranges::for_each(view, show);
        std::ranges::for_each(view, show);
    }

输出：

    cppreference.com
    en.wikipedia.org
    cppreference.com
    en.wikipedia.org

### 参阅

ranges::transform (C++20) | 将一个函数应用于某一范围的各个元素 (niebloid)