字符编码之间的转换很难正确进行。QString 存储 16 位 UTF-16。 toStdString使用中间字节数组将其重新编码为 utf-8 toUtf8。
QStringView也有toUtf8返回 aQByteArray并具有与 相同的保证QString。
std::string toStdString( QStringView view ) {
auto bytes = view.toUtf8(); // allocates and converts.
return {bytes.constData(), bytes.length()}; // copies to a std::string
}
Run Code Online (Sandbox Code Playgroud)
与天真的相比,这会减少 1 个内存副本
std::string toStdString( QStringView view ) {
return QString(view).toStdString();
}
Run Code Online (Sandbox Code Playgroud)
理论上,有 1 个中间内存副本也可以删除;您可以直接从 UTF16 QStringView 数据转换为std::string.
std::string toStdString( QStringView view ) {
auto toUtf8 = QStringEncoder(QStringEncoder::Utf8);
auto space = toUtf8.requiredSpace(view.length());
std::string retval;
// make a string of all nulls:
retval.resize(space+1); // +1 probably not needed
// Ideally use C++23's `resize_and_overwrite`
// instead of `resize` above. Without that, on large (>1k)
// strings other solutions are faster.
// output the UTF8 into the std::string:
char* end = toUtf8.appendToBuffer(retval.data(), view);
// Strip the nulls logically from the returned string:
retval.resize(end-retval.data());
return retval;
}
Run Code Online (Sandbox Code Playgroud)
这是为了避免中间缓冲区分配。它可能不正确并且存在错误,但设计是合理的。
理论上,一个更疯狂的系统可以在创建输出缓冲区之前(或在您创建输出缓冲区时)计算出 UTF16 所需的实际空间。
(由于 @BenjaminBuch 在另一个答案中的出色分析而添加了 resize_and_overwrite 优化)。