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

时间:2012-08-25 11:22:56

标签: c++ string std qstring expression-templates

Qt的QString可以由operator%连接,operator+使用表达式模板预先计算结果字符串的大小,并优化对std::basic_string的几个链式调用。有关详细信息,请参阅this question of mine

为什么{{1}}没有采用类似的结构?这甚至是每个C ++ 11允许的吗?我看到只有优点,显然ABI兼容性可以被库实现者在他们想要的时候打破(并且C ++ 11提供了一个很好的理由,即使对于libstdc ++)。

2 个答案:

答案 0 :(得分:5)

因为没人提出这个标准;除非有人提出某些建议,否则它不会进入。此外,因为它可能会破坏现有代码(如果他们使用的是operator+)。

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

答案 1 :(得分:1)

在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-semantics从赋值运算符右侧创建的临时r值“窃取”内存,从而阻止连接字符串的副本。