#c #qt #visual-studio-2012 #lambda
#c #qt #visual-studio-2012 #лямбда
Вопрос:
Я хочу сохранить файл внутри лямбда-функции. Я могу работать с ним вне лямбда-выражения, но как только я передаю его в качестве ссылки и хочу проверить его существование после его загрузки, мое приложение выходит из строя в этой строке : if (workFile.exists() amp;amp; !workFile.remove()) {
.
QFile workFile("path/to/file.bat");
[..]
if (!workFile.exists()) {
[..] download file amp; such
QObject::connect(amp;mng, amp;FileManager::onDownload, this, [=, amp;workFile] (const QStringamp; name) {
if (workFile.exists() amp;amp; !workFile.remove()) {
qDebug() << "File was not downloaded correctly.";
}
});
}
Обратная трассировка:
Почему это не работает? Как я должен правильно захватить QFile?
Комментарии:
1. @Mike Хороший улов, опубликуйте его в качестве ответа!
Ответ №1:
При захвате объекта по ссылке, если лямбда-выражение вызывается после окончания срока службы объекта, вы получаете висячую ссылку. Вы всегда должны убедиться, что объекты, передаваемые по ссылке, остаются действительными при вызове лямбда-выражения.
В вашем примере QFile
объект выходит за пределы области видимости до фактического вызова лямбда-выражения, это происходит потому, что ваш FileManager
emits onDownload
после завершения вашей функции, лямбда-выражение получает ссылку на недопустимый объект, и вы получаете сбой.
Вы можете решить эту проблему, создав другой QFile
экземпляр с тем же именем файла внутри лямбды (вместо захвата старого) или используя статические альтернативы (если вы просто хотите проверить наличие и удалить): QFile::exists()
, QFile::remove()
.
Если вам действительно нужно захватить старый QFile
экземпляр, вы должны убедиться, что его время жизни действительно при вызове лямбда-выражения (вы можете сделать это, выделив его в куче, используя new
и delete
редактируя его самостоятельно, когда закончите).