如何防止QStringBuilder超出其初始化的作用域
How to prevent QStringBuilder from outliving the scope it was initialised in
我一直在考虑改变一些代码,以利用QStringBuilder
表达式模板来实现所谓的性能改进。不幸的是,这导致我的代码部分开始在某些地方崩溃,示例如下:
#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
导致之前工作的代码崩溃,甚至没有发出警告,这意味着我现在将避免在其他地方使用它,除非我能保证这种情况不会再次发生。因为在这种情况下,RVO可以防止任何复制的发生,我不认为通常禁用对象复制的技术会起作用。是否有一种方法可以防止这种情况在QStringBuilder
或类似的表达式模板中发生,或者是维护对自动变量的引用的对象总是不安全的?
lambda应该返回一个显式类型:
[]() -> Type { }
or
[]() -> QString { }
clazy
代码检查器为这个场景提供了一个检查
相关文章:
- 在类函数中初始化外部作用域变量
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- 函数作用域是静态变量还是线程本地变量在C++11中的第一个条目中初始化
- 使用作用域内生成的指针初始化静态成员
- 主线程中块作用域static与命名空间作用域thread_local的初始化和销毁顺序
- 在c++中,全局作用域中只允许"表达式"初始化全局对象.我在哪里可以在标准中找到这个
- 有没有一个C++版本在循环结束后将在for循环初始化中声明的变量保留在作用域中
- 使用具有相同名称的(无作用域)基类枚举初始化派生类枚举
- 函数作用域的静态非 Pod 对象初始化
- 是一个初始化为未确定值或未初始化的本地作用域变量
- 是块作用域静态或线程存储持续时间变量初始化失败的原因
- 为什么可以在没有初始化项的情况下跳转到标量类型对象的作用域?
- 静态成员初始化器的Lambda作用域
- 命名空间作用域变量的c++初始化
- 如何在结构声明中初始化位域
- c++中如何初始化全局作用域的静态成员
- 扩展在if/else序列中初始化的变量的作用域
- 如何防止QStringBuilder超出其初始化的作用域
- 条件运算符是在全局作用域中初始化全局变量的唯一方法
- 提升不同版本的序列化作用域