我以前解析数字。
一直用 std::stoi。
直到有一天。
线上 CPU 飙了。
你看 profile。
全在解析日志。
那一刻你才意识到。
“方便”有时就是“贵”。
当年:stoi/stringstream 很顺手,但它们有隐藏成本
std::stoi 会做很多事。
会处理异常。
会处理 locale。
有时还会分配。
std::stringstream 更是重量级。
你在热路径里用它。
就像用卡车搬快递。
线上啪一下:解析失败直接抛异常,日志线程被拖死
假设你写了个小项目。
从一行文本里读一个数字。
线上偶尔会出现脏数据。
int x = std::stoi(s); // 失败会抛异常
异常如果被频繁触发。
性能会很难看。
而且你得处处 try/catch。
一不小心就把错误吞掉。
C++17:from_chars,像 C 一样直接
#include <charconv>
int value = 0;
auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value);
这里有两个返回值。
ptr 指向解析停止的位置。
ec 是错误码。
你不用异常也能判断是否成功。
if (ec != std::errc{}) {
handle_bad_input();
}
to_chars:把数字写回字符缓冲区
#include <charconv>
char buf[32];
auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), value);
成功时。
ptr 指向写入结束的位置。
你可以用它构造 string。
std::string out(buf, ptr);
你会问:那它和 snprintf 有啥区别
直觉上确实很像。
但 to_chars 不走格式化那套。
它更专注。
也更可控。
而且不受 locale 影响。
关键结论
from_chars/to_chars 的价值是。
把数字解析变成“无分配、无异常、可控的底层工具”。
小结:热路径别贪方便,给解析一点尊重
当年我们用 stoi。
图的是省事。
但在热路径里。
省事可能就是大坑。
C++17 给了 from_chars/to_chars。
它不花哨。
但很适合写性能敏感的基础设施。