如何防止QStringBuilder比它初始化的范围更长 [英] How to prevent QStringBuilder from outliving the scope it was initialised in

查看:190
本文介绍了如何防止QStringBuilder比它初始化的范围更长的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在改变一些代码,以利用 QStringBuilder 表示模板声称性能提高。不幸的是,这导致我的代码部分开始崩溃的地方,例如:

I have been looking at changing some code to make use of QStringBuilder expression template for its purported performance improvements. Unfortunately this resulted in sections of my code starting to crash in places, an example of which follows:

#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表达式的返回类型被推导到< code> QStringBuilder< QStringBuilder< QString,const char [3]>,QString> ,它返回后尝试转换为 QString 分配给 accumulate 结果。此强制类型崩溃,因为它试图使用对在lambda范围内并且已被破坏的对象的引用。这个崩溃可以通过明确指定lambda的返回类型来修复,例如 [](const QString& s,int i) - >

The reason this crashes is because the return type of the lambda expression is deduced to be QStringBuilder<QStringBuilder<QString,const char [3]>,QString> which after being returned attempts to cast to QString to assign to the accumulate result. This cast crashes because it is attempting to use references to objects which were in the scope of the lambda and have now been destroyed. This crash can be fixed by explicitly specifying the return type of the lambda as such [](const QString& s, int i) -> QString which ensures that the cast occurs before the closure is exited.

但是,启用 QStringBuilder 这里导致崩溃在以前工作的代码,甚至没有发出警告意味着我现在将避免使用它在其他地方,除非我可以保证这不会再发生。因为在这种情况下,RVO可以防止任何复制发生,我不认为禁用复制对象的通常技术将工作。有没有办法防止在 QStringBuilder 或类似的表达式模板中发生这种情况,或者保持对自动变量的引用总是使用不安全的对象?

However the fact that enabling QStringBuilder here caused a crash in previously working code without even emitting a warning means that I will now avoid using it elsewhere unless I can guarantee that this will not happen again. Since in this case RVO could prevent any copying from occurring I don't think the usual technique of disabling copying of the object would work. Is there a way to prevent this occurring in QStringBuilder or similar expression templates or are objects which maintain references to automatic variables always going to be unsafe to use?

推荐答案

lambda应该返回一个显式类型:

The lambda should return an explicit type:

[]() -> Type { }

or 

[]() -> QString { }

这篇关于如何防止QStringBuilder比它初始化的范围更长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆