Я искал изменение некоторого кода, чтобы использовать шаблон выражения QStringBuilder
для его purported performance improvements. К сожалению, это привело к разделам моего кода начинает врезаться в местах, пример которого следует:Как предотвратить 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);
});
}
Причина этого происходит сбой, потому что возвращаемый тип лямбда-выражения выводится как QStringBuilder<QStringBuilder<QString,const char [3]>,QString>
, который после того, как возвращаемые попытки для приведения к QString
, чтобы присвоить результат accumulate
. Этот бросок падает, потому что он пытается использовать ссылки на объекты, которые были в области лямбда и теперь уничтожены. Этот крах может быть исправлен путем явного указания типа возврата лямбда как такового [](const QString& s, int i) -> QString
, который гарантирует, что литье происходит до закрытия закрытия.
Однако факт, что включение QStringBuilder
здесь вызвало сбой в предыдущем рабочем коде, даже не выпустив предупреждение, я теперь избегу использовать его в другом месте, если не могу гарантировать, что это не повторится. Поскольку в этом случае RVO может предотвратить любое копирование, я не думаю, что обычная техника отключения копирования объекта будет работать. Есть ли способ предотвратить это в QStringBuilder
или аналогичных шаблонах выражений или объекты, которые поддерживают ссылки на автоматические переменные, которые всегда будут небезопасными в использовании?
Это ошибка Qt. Если вы еще не подали заявку, пожалуйста, напишите ее, и она должна быть исправлена быстро. –
'QStringBuilder' совместим с C++ 11, но не совместим с C++ 14 на данный момент ... Это, по сути, вопрос C++ 14, а не C++ 11. –
@KubaOber Обратные типы лямбда-выражений с одним оператором return не должны указываться в C++ 11, что и вызывает эту проблему. – sjdowling