std::transform是STL中用于批量元素映射的算法,支持单序列一元变换和双序列二元变换,要求输出空间预先分配或使用back_inserter等插入迭代器,禁止重叠读写与有副作用操作。

std::transform 是 STL 中最常用、最灵活的批量处理算法之一,核心作用是把一个或两个输入范围的元素,按指定规则转换后,写入到目标位置。它不改变原容器大小,只做“映射”操作。
单序列变换:一元操作
最常见用法:对一个容器每个元素执行相同操作,结果存入另一容器(或原地覆盖)。
- 要求目标容器提前分配好空间(或用 back_inserter),否则越界未定义
- 可原地操作——输入和输出迭代器指向同一容器,只要保证不重叠读写(如正向遍历+正向写入通常安全)
示例:把 vector 全部平方并存回原容器
vector v = {1, 2, 3, 4};
std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x * x; });
// v 变为 {1, 4, 9, 16}双序列变换:二元操作
用两个输入序列对应位置元素,通过二元函数生成结果。常用于向量加法、点积预处理等。
立即学习“C++免费学习笔记(深入)”;
- 两个输入范围必须等长;第三个参数是输出起始位置,输出空间需足够
- 三个迭代器不能相互重叠导致未定义行为(例如输出指向第一个输入的中间位置,可能被提前改写)
示例:两个 vector 相加,结果存入第三个 vector
vector a = {1, 2, 3}, b = {10, 20, 30}, c(3);
std::transform(a.begin(), a.end(), b.begin(), c.begin(), std::plus());
// c 变为 {11, 22, 33}配合 inserter 或 back_inserter 动态扩容
当目标容器初始为空,又想用 transform 填充时,不能直接传 begin()——那会写入无效地址。得用插入迭代器。
-
back_inserter(c):调用 push_back,适合 vector、deque
-
inserter(c, c.begin()):在指定位置 insert,适合 list、set(但注意 set 不支持随机插入位置语义)
示例:从字符串提取大写字母,追加到 vector
string s = "Hello World";
vector upper;
std::transform(s.begin(), s.end(), back_inserter(upper),
[](char c) { return std::isupper(c) ? c : '\0'; });
// 注意:这会把非大写变 '\0';若只想保留大写,需配合 remove_copy_if 等组合常见易错点提醒
- 输出迭代器指向的空间必须可写且容量足够——这是运行时崩溃的高频原因
- lambda 捕获要谨慎:若 transform 在多线程中调用,避免捕获局部变量地址
- 函数对象不能有副作用(比如修改外部计数器),因为标准不保证执行顺序,且可能被并行化(C++17 起支持执行策略)
- 对 string 使用 transform 时,注意字符类型是 char 还是 unsigned char——toupper/tolower 要求 unsigned char 或 EOF,否则可能误触发负值行为
以上就是c++++的std::transform算法怎么用 对容器元素进行批量操作【STL算法】的详细内容,更多请关注php中文网其它相关文章!