为什么 std::basic_string 不支持通过表达式模板进行串联?



Qt 的 QString s 可以通过 operator% 连接起来,它使用表达式模板预先计算结果字符串的大小并优化对operator+的几个链式调用。有关更多信息,请参阅我的这个问题。

为什么std::basic_string没有改编类似的结构?这甚至允许每C++11吗?我只看到优势和明显的 ABI 兼容性可以被库实现者在需要时破坏(C++11 甚至为 libstdc++ 提供了一个很好的理由(。

因为没有人提出它作为标准; 除非有人提出什么,否则它不会进入。还因为它可能会破坏现有代码(如果他们使用operator+那就是(。

此外,表达式模板在存在auto的情况下效果不佳。做auto concat = str1 % str2;这样简单的事情很容易被打破。希望这是C++17将通过某种方式解决的问题。

在 C++11 中,std::basic_string 支持移动语义,这意味着您可以通过为系列中的第一个字符串分配内存来operator+优化一系列字符串的串联,然后简单地在系列中第一个字符串的内存中构造其余字符串,从而大大减少连接和返回一系列字符串所需的内存分配和副本数量。

我相信正如您使用Qt的方法指出的那样,可以进行进一步的优化,但是C++11允许的移动语义克服了C++03版本的std::basic_string中存在的巨大性能障碍,尤其是在将大量字符串连接在一起时。

例如,类似

std::string a = std::string("Blah blah") + " Blah Blah " + " Yadda, Yadda";

可以通过为第一个字符串分配内存,然后使用 move 语义,从第一个字符串中"窃取"剩余内存以就地构造第二个字符串来完成,并且仅在额外空间不足时才重新分配内存。 最后,赋值运算符可以使用移动语义从赋值运算符右侧创建的临时 r 值中"窃取"内存,从而阻止串联字符串的副本。

相关内容

最新更新