我正在尝试使用shared_ptr在lambda之间共享同一对象(在我的情况下为字符串):
auto fileToLoad = make_shared<string>();
StartAsync(
[=]()
{
QDir dir(dirPath.c_str());
QString fileExtension(fileExt.c_str());
for (int i = 0; i < 150; i++)
{
auto files = dir.entryList(QStringList() << fileExtension << fileExtension.toUpper(), QDir::Files);
if (!files.empty())
{
//fileToLoad.reset(new string(files.first().toUtf8().constData()));
fileToLoad = make_shared<string>(files.first().toUtf8().constData());
break;
}
this_thread::sleep_for(chrono::milliseconds(200));
}
},
[=]()
{
if (fileToLoad == nullptr)
{
DisplayMessage("Timeout reached");
}
else
{
doFunc(*fileToLoad);
}
});
经过多次尝试,我仍然无法按照我的意愿使其工作:将fileToLoad存储在第一个lambda中,并在第二个lambda中使用它。或由于限定符(const)而无法编译,或者编译但'fileToLoad'保持为空。
如您所见,我正在尝试使用StartAsync函数通知文件是否已出现在文件夹中,该函数需要2 lambda(此函数基本上会创建QObjects并将其移至后台线程,然后在信号和插槽之间建立一些连接)。
编辑:
StartAsync:需要一个任务的lambda(冗长的工作)和一个后任务的lambda(UI更新)
void MainWidget::StartAsync(function<void()> func, function<void()> postTask)
{
AsyncTask* task = new AsyncTask(func, [=]() { if (postTask != nullptr) { postTask(); HideProgressBar(); }});
QThread* thread = new QThread();
task->moveToThread(thread);
connect(thread, &QThread::started, this, &MainWidget::ShowProgressBar);
connect(thread, &QThread::started, task, &AsyncTask::RunTask);
connect(task, &AsyncTask::TaskFinished, task, &AsyncTask::RunPostTask);
connect(thread, &QThread::finished, task, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
thread->start();
}
任何建议都值得赞赏。
答案 0 :(得分:2)
将新值分配给std::shared_ptr
时-创建一个新的共享值,该共享值与上一个共享值没有任何关系(可以查看两个shared_ptrs的计数器)。您应该更改
fileToLoad = make_shared<string>(files.first().toUtf8().constData());
到
*fileToLoad = files.first().toUtf8().constData()
(当然要事先检查fileToLoad不为空)
答案 1 :(得分:0)
您的代码将无法工作,因为在第一个lambda中,您将覆盖lambda中的临时指针。您可以做的是在指针后面覆盖std::string
,它应该可以正常工作:
auto fileToLoad = make_shared<string>();
StartAsync(
[=]()
{
QDir dir(dirPath.c_str());
QString fileExtension(fileExt.c_str());
for (int i = 0; i < 150; i++)
{
auto files = dir.entryList(QStringList() << fileExtension << fileExtension.toUpper(), QDir::Files);
if (!files.empty())
{
//fileToLoad.reset(new string(files.first().toUtf8().constData()));
*fileToLoad = files.first().toStdString();
break;
}
this_thread::sleep_for(chrono::milliseconds(200));
}
},
[=]()
{
if (fileToLoad == nullptr)
{
DisplayMessage("Timeout reached");
}
else
{
doFunc(*fileToLoad);
}
});