在两个Lambda之间共享对象

时间:2019-04-10 08:24:43

标签: c++ lambda shared-ptr

我正在尝试使用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();
}

任何建议都值得赞赏。

2 个答案:

答案 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);
        }
    });