// <algorithm> 
// 一元操作符(1)
template <class InputIterator,
    class OutputIterator,
    class UnaryOperation>
    OutputIterator transform (
        InputIterator first1,
        InputIterator last1,
        OutputIterator result,
        UnaryOperation op);
// 二元操作符(2)
template <class InputIterator1,
    class InputIterator2,
    class OutputIterator,
    class BinaryOperation>
    OutputIterator transform (
        InputIterator1 first1,
        InputIterator1 last1,
        InputIterator2 first2,
        OutputIterator result,
        BinaryOperation binary_op);

对指定范围中的每个元素调用某个函数以改变元素的值。

该函数等价于:

template<class _InIt,
    class _OutIt,
    class _Fn1> inline
    _OutIt _Transform(_InIt _First, _InIt _Last,
        _OutIt _Dest, _Fn1 _Func)
    {    // transform [_First, _Last) with _Func
        for (; _First != _Last; ++_First, ++_Dest)
            *_Dest = _Func(*_First);
        return (_Dest);
    }
  • first1last1

    分别指向第一个序列中初始及末尾位置的输入迭代器(Input iterators)。这个范围即 [first1,last1) ,包括 first1 到 last1 间的所有元素,包括 first1 指向的元素,但不包括 last1 指向的元素。

    first2

    指向第二个序列中初始位置的输入迭代器。当前函数最多访问该序列中与范围 [first1,last1)  中相同元素个数的元素。

    result

    指向目标序列初始位置的输出迭代器(Output iterators)。该范围包含与范围 [first1,last1)  中相同元素个数的元素。

    op

    一元谓词(Unary)函数,以范围中的一个元素为参数,然后返回一个可转换成由 OutputIterator 所指向的类型的值。

    其返回值表明指定元素是否满足当前函数所检测的条件。

    该函数不能修改其参数。

    可以是函数指针(Function pointer)类型或函数对象(Function object)类型。

    binary_op

    二元谓词(Binary)函数,以两个元素为参数,然后返回一个可转换成由 OutputIterator 所指向的类型的值。

    其返回值表明指定两个元素是否满足当前函数所检测的匹配条件。

    该函数不能修改其参数。

    可以是函数指针(Function pointer)类型或函数对象(Function object)类型。

    返回

    返回一个迭代器,该迭代器指向最后一个写入 result 序列的元素之后的元素。

  • 例 1

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    
    #define CLASSFOO_VECTOR(type, name, ...) \
    static const type name##_a[] = __VA_ARGS__; \
    std::vector<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))
    
    namespace ClassFoo{
        int Inc(int n) {
            return ++n;
        }
        void Transform_1() {
            // 构造一个向量
            CLASSFOO_VECTOR(int, BigVector, { 8, 23, 5, 6, 7, 29, 0, 5, 6, 7, 1, 1 });
            std::vector<int> TargetVector;
            TargetVector.resize(BigVector.size());
    
            // 一元谓词
            // 将 BigVector 中元素值加 1 后输出到 TargetVector
            std::transform(BigVector.begin(), BigVector.end(), TargetVector.begin(), Inc);
    
            // 打印 TargetVector 中的内容
            std::copy(
                TargetVector.begin(),
                TargetVector.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
    
            // 二元谓词
            // 将 BigVector 与 TargetVector 中的对应元素相加,并输出到 BigVector 中
            std::transform(
                BigVector.begin(),
                BigVector.end(),
                TargetVector.begin(),
                BigVector.begin(),
                std::plus<int>());
    
            // 打印 BigVector 中的内容
            std::copy(
                BigVector.begin(),
                BigVector.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Transform_1();
        return 0;
    }

    9 24 6 7 8 30 1 6 7 8 2 2 
    17 47 11 13 15 59 1 11 13 15 3 3 

    例 2

    C++11

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    
    namespace ClassFoo{
        void Transform_2() {
            // 构造一个向量
            std::vector<int> BigVector = { 8, 23, 5, 6, 7, 29, 0, 5, 6, 7, 1, 1 };
            std::vector<int> TargetVector;
            TargetVector.resize(BigVector.size());
    
            // 一元谓词
            // 将 BigVector 中元素值加 1 后输出到 TargetVector
            std::transform(
                BigVector.begin(),
                BigVector.end(),
                TargetVector.begin(),
                [](int m) { return ++m; });
    
            // 打印 TargetVector 中的内容
            std::copy(
                TargetVector.begin(),
                TargetVector.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
    
            // 二元谓词
            // 将 BigVector 与 TargetVector 中的对应元素相加,并输出到 BigVector 中
            std::transform(
                BigVector.begin(),
                BigVector.end(),
                TargetVector.begin(),
                BigVector.begin(),
                [](int m, int n) { return m + n; });
    
            // 打印 BigVector 中的内容
            std::copy(
                BigVector.begin(),
                BigVector.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Transform_2();
        return 0;
    }

    9 24 6 7 8 30 1 6 7 8 2 2 
    17 47 11 13 15 59 1 11 13 15 3 3 

    例 3

    大小写转换

    #include <iostream>
    #include <algorithm>
    #include <string>
    
    namespace ClassFoo{
        void Transform_3() {
            std::string foo = "classfoo.com";
            // 将字符串转成大小
            std::transform(foo.begin(), foo.end(), foo.begin(), ::toupper);
            std::cout << foo << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Transform_3();
        return 0;
    }

    CLASSFOO.COM

    例 4

    改变向量的内容并输出到流中

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    
    namespace ClassFoo{
        int Inc(int n) {
            return ++n;
        }
        void Transform_4() {
            std::vector<int> foo;
            foo.push_back(22);
            foo.push_back(99);
            // 改变向量,且输出到流中
            std::transform(
                foo.begin(),
                foo.end(),
                std::ostream_iterator<int>(std::cout, " "), Inc);
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Transform_4();
        return 0;
    }

    23 100 

  • 复杂度

    O(n)n 为 last first

    数据争用相关

    访问在范围 [first1,last1) 中的所有元素,且每个元素确定只被访问一次。

    修改在范围 result 及返回值之间的所有元素。

    异常安全性相关

    如果谓词(opbinary_op)、元素赋值操作或操作某个迭代器抛异常,该函数才会抛异常。

    注意 无效参数将导致未定义行为(Undefined behavior)