c++ std::transform算法怎么用 c++ STL数据转换【实例】

std::transform 是 C++ STL 中用于批量转换数据的通用算法,支持单序列一元变换(如平方、转大写)、双序列二元运算(如向量加法)、就地转换及配合 back_inserter 动态扩容,要求目标空间足够或满足不重叠写入条件。

std::transform 是 C++ STL 中用于批量转换数据的通用算法,核心作用是把一个(或两个)输入范围的元素,按指定规则处理后,写入到目标位置。它不改变原容器大小,只做“映射”操作,类似函数式编程里的 map。

单序列转换:一元操作

最常用场景:对容器每个元素做统一变换,比如全部转大写、平方、取绝对值等。

  • 需要提供起始/结束迭代器、目标起始迭代器、一个可调用对象(lambda、函数指针、函数对象)
  • 目标容器必须有足够空间(可用 back_inserter 扩容,但注意性能)

示例:把 vector 中每个数平方

vector src = {1, 2, 3, 4};
vector dst(src.size()); // 预分配空间
std::transform(src.begin(), src.end(), dst.begin(), [](int x) { return x * x; });
// dst → {1, 4, 9, 16}

双序列合并转换:二元操作

用两个输入范围,对应位置元素一起参与运算,结果写入目标位置。两范围长度需一致(或至少保证不越界)。

  • 传入两个输入迭代器对,一个输出起始,一个接受两个参数的可调用对象
  • 常用于向量加法、逐元素乘积、字符串拼接等

示例:两个 vector 对应相加

vector a = {1, 2, 3};
vector b = {10, 20, 30};
vector res(a.size());
std::transform(a.begin(), a.end(), b.begin(), res.begin(), std::plus());
// res → {11, 22, 33}

目标写入到源容器自身(就地转换)

只要目标起始位置与源不重叠(或严格满足“输出不覆盖未读取输入”),就可以直接写回原容器。

  • 常见于修改原容器内容,如全部变负、转小写
  • 避免用 end() 当目标起点;用 begin() 是安全的(因 transform 顺序读取+写入)

示例:字符串每个字符转小写

string s = "ABC";
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
// s → "abc"

配合 inserter 或 back_inserter 动态扩容

当目标容器初始为空,又想自动追加结果时,可用插入迭代器。

  • back_inserter 适用于支持 push_back 的容器(vector、deque、list)
  • 注意:频繁 push_back 可能引发多次内存重分配,预估大小更高效

示例:从 set 提取偶数并放入新 vector

set nums = {1, 2, 3, 4, 5};
vector evens;
std::transform(nums.begin(), nums.end(), back_inserter(evens),
[](int x) { return x * 2; });
// evens → {2, 4, 6, 8, 10}