std::transform要求目标容器预先分配足够空间或使用back_inserter,因它不负责内存分配;必须匹配一元/二元函数签名,且二元变换时第二输入范围长度不得小于第一范围。

直接用 std::transform 就行,但得配对好迭代器范围、转换函数和目标位置——漏一个就编译失败或越界写入。
为什么 std::transform 第三个参数必须是目标起始迭代器,不能是容器引用
因为 std::transform 不负责内存分配,它只按需写入。目标容器必须提前有足够空间(比如用 resize() 或初始化为同尺寸),否则写入会越界。
- 错误写法:
std::vector
src = {1,2,3};
std::vectordst;
std::transform(src.begin(), src.end(), dst.begin(), [](int x) { return x * 2; }); // dst.begin() 是空迭代器,写入未定义行为 - 正确写法(预分配):
std::vector
src = {1,2,3};
std::vectordst(src.size()); // 关键:先 resize 或构造同尺寸
std::transform(src.begin(), src.end(), dst.begin(), [](int x) { return x * 2; }); - 也可用
std::back_inserter(但性能略低):std::vector
dst;
std::transform(src.begin(), src.end(), std::back_inserter(dst), [](int x) { return x * 2; });
std::transform 支持一元和二元操作,别传错函数签名
一元变换单个容器(如每个元素平方),二元变换两个源容器(如对应元素相加)。传错会导致编译器报 “no match for call” 类错误。
- 一元:两个输入迭代器 + 一个输出迭代器 + 一元函数
std::transform(a.begin(), a.end(), b.begin(), [](int x) { return x + 1; }); - 二元:两个输入迭代器对 + 一个输出迭代器 + 二元函数
std::transform(a.begin(), a.end(), b.begin(), c.begin(), [](int x, int y) { return x + y; }); // a[i] + b[i] → c[i] - 注意:二元版第二个输入范围长度必须 ≥ 第一个,否则行为未定义
对 std::string 或 std::vector 做 in-place 转换要小心 const_iterator
如果想原地修改(比如转小写),目标迭代器必须是 begin(),且不能用 cbegin() —— 否则编译失败,提示 “assignment of read-only location”。
立即学习“C++免费学习笔记(深入)”;
- 正确(in-place):
std::string s = "ABC";
std::transform(s.begin(), s.end(), s.begin(), ::tolower); // 注意 ::tolower 防止重载歧义 - 错误(用 const 迭代器):
std::transform(s.cbegin(), s.cend(), s.begin(), ::tolower); // 编译不过:不能用 cbegin 做输入又期望可写
- 若用 lambda 处理宽字符或自定义逻辑,记得返回值类型匹配目标元素类型,比如
std::string里用char,别返回int
最常被忽略的是目标容器容量检查和二元变换时的长度对齐——这两个地方出问题,程序不一定立刻崩,但结果错得悄无声息。










