最直接方法是调用 insert(0, str) 或 insert(0, count, ch),时间复杂度 O(n);频繁开头插入应改用 deque 或预分配 vector,避免性能退化。

用 std::string::insert() 在开头插入字符最直接
直接调用 insert(),传入位置 0 和待插入的字符或字符串即可。它本质是内存前移,时间复杂度 O(n),但语义清晰、无歧义。
常见错误是误用 push_back()(只能尾部)或写错索引(比如传 1 以为是开头)。
-
s.insert(0, "x");—— 插入字符串字面量,注意双引号 -
s.insert(0, 1, 'x');—— 插入 1 个字符'x',第二个参数是数量,不是字符本身 - 避免
s.insert(s.begin(), 'x');虽然可行,但迭代器版本在s为空时虽安全,可读性不如索引版,且不必要地引入迭代器操作
频繁开头插入时性能会明显变差
每次 insert(0, ...) 都要将整个字符串内容向后搬移,1000 次插入长度为 100 的字符串,可能触发数十次内存重分配和百万级字节拷贝。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
如果你的逻辑本质是“不断往前面加东西”(比如解析逆序 token、构建前缀表达式),说明数据结构选错了:
立即学习“C++免费学习笔记(深入)”;
- 改用
std::deque<char></char>:支持 O(1) 头部插入,最后用std::string(deq.begin(), deq.end())构造结果 - 先用
std::vector<:string></:string>存各段,最后std::accumulate或反向拼接,避免反复移动 - 预估总长?可用
reserve()减少重分配,但无法消除移动开销
注意空字符串和多字节字符的边界情况
insert(0, ...) 对空字符串完全合法,不会崩溃,这是标准保证的行为;但如果你插的是 UTF-8 编码的中文字符(如 "你好"),得确保整个 string 保持合法 UTF-8 序列——std::string 本身不校验编码,插错位置可能产生乱码,这不是 API 问题,而是业务层需自行保障。
- 空串操作:
std::string s; s.insert(0, "a");→ 结果是"a",没问题 - 插单个非 ASCII 字符:
s.insert(0, "\xe4\xbd\xa0");(UTF-8 编码的“你”)必须整组字节一起插,不能只插第一个字节 - 不要对
std::u16string或std::u32string用insert(0, "x")—— 字面量类型不匹配,编译失败
str.insert(0, 1, c) 足够。真正卡住人的往往不是语法,而是没意识到“开头插入”这个动作在底层意味着整块内存挪动——一旦循环里这么干,性能拐点来得比想象中快。

















