我一直在研究更改一些代码以将 QStringBuilder
表达式模板用于purported performance improvements。不幸的是,这导致我的代码部分开始在某些地方崩溃,其示例如下:
#define QT_USE_QSTRINGBUILDER
#include <numeric>
#include <vector>
#include <QString>
#include <QStringBuilder>
int main()
{
std::vector<int> vals = {0, 1, 2, 3, 4};
QString text = "Values: " + QString::number(vals[0]);
text = std::accumulate(vals.begin() + 1, vals.end(), text, [](const QString& s, int i)
{
return s + ", " + QString::number(i);
});
}
崩溃的原因是因为lambda表达式的返回类型被推导为
QStringBuilder<QStringBuilder<QString,const char [3]>,QString>
,在返回后尝试转换为QString
以分配给accumulate
结果。该强制转换崩溃是因为它试图使用对lambda范围内的对象的引用,而这些对象现在已被销毁。可以通过将lambda的返回类型明确指定为[](const QString& s, int i) -> QString
来解决此崩溃,该QStringBuilder
确保强制转换在退出闭包之前进行。但是,此处启用
QStringBuilder
导致先前工作的代码崩溃甚至没有发出警告的事实,这意味着我现在将避免在其他地方使用它,除非我可以保证不会再次发生这种情况。因为在这种情况下,RVO可以防止任何复制的发生,所以我认为禁用对象复制的常规技术不起作用。有没有办法防止这种情况在ojit_code或类似的表达式模板中发生,还是维护对自动变量的引用的对象总是不安全地使用? 最佳答案
lambda应该返回一个显式类型:
[]() -> Type { }
or
[]() -> QString { }
关于c++ - 如何防止QStringBuilder超出其初始化范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32476634/