2015-09-09 7 views
2

Я искал изменение некоторого кода, чтобы использовать шаблон выражения 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 или аналогичных шаблонах выражений или объекты, которые поддерживают ссылки на автоматические переменные, которые всегда будут небезопасными в использовании?

+0

Это ошибка Qt. Если вы еще не подали заявку, пожалуйста, напишите ее, и она должна быть исправлена ​​быстро. –

+0

'QStringBuilder' совместим с C++ 11, но не совместим с C++ 14 на данный момент ... Это, по сути, вопрос C++ 14, а не C++ 11. –

+0

@KubaOber Обратные типы лямбда-выражений с одним оператором return не должны указываться в C++ 11, что и вызывает эту проблему. – sjdowling

ответ

0

лямбда должен возвращать явный тип:

[]() -> Type { } 

or 

[]() -> QString { } 
+0

Я упоминаю в вопросе, что это устраняет проблему для этого экземпляра, но я не хочу исправлять этот конкретный сбой, а сам класс 'QStringBuilder', поскольку спецификация типа возврата не является обязательной для lambdas и даже не для функций в C++ 14. В настоящее время риск возникновения сбоя в этом неявном поведении является неприемлемым. – sjdowling

+0

Э-э, я должен был прочитать вопрос полностью или, возможно, это было добавлено позже. – AlexanderVX

 Смежные вопросы

  • Нет связанных вопросов^_^