Jinesi Yelizati
Jinesi Yelizati

Reputation: 321

Why it is not possible to use unique_ptr in QFuture?

Here is my sample code, I am using std::vector<std::unique_ptr<std::string>> as future result.

#include "mainwindow.h"
#include <QLineEdit>
#include <QtConcurrent/QtConcurrent>
#include <vector>

MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent) {
    auto model = new QLineEdit(this);
    this->setCentralWidget(model);

    auto watcher = new QFutureWatcher<std::vector<std::unique_ptr<std::string>>>(/*this*/);
    auto future  = QtConcurrent::run([this]() -> std::vector<std::unique_ptr<std::string>> {
        std::vector<std::unique_ptr<std::string>> res;
        for (int k = 0; k < 100; ++k) {
            auto str = std::make_unique<std::string>("Hi");
            res.push_back(std::move(str));
        }
        return res;
    });

    connect(watcher, &QFutureWatcher<std::vector<std::unique_ptr<std::string>>>::finished, this, [=]() {
        for (const auto &item : future.result()){
            model->setText(model->text() + QString::fromStdString(*item));
        }
        delete watcher;
    });
    watcher->setFuture(future);
}

MainWindow::~MainWindow() {

}

But this code can't compile. Here is the log,

/Users/ii/QT/qt-everywhere-src-6.2.0-beta4/include/QtCore/qfuture.h:328:12: note: in instantiation of member function 'std::vector<std::unique_ptr<std::string>>::vector' requested here
    return d.resultReference(0);
           ^
/Users/ii/CLionProjects/simpleQT/mainwindow.cpp:22:40: note: in instantiation of function template specialization 'QFuture<std::vector<std::unique_ptr<std::string>>>::result<std::vector<std::unique_ptr<std::string>>, void>' requested here
        for (const auto &item : future.result()){
                                       ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/usr/include/c++/v1/__memory/base.h:103:16: note: candidate template ignored: substitution failure [with _Tp = std::unique_ptr<std::string>, _Args = <std::unique_ptr<std::string> &>]: call to implicitly-deleted copy constructor of 'std::unique_ptr<std::string>'
constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
               ^

Upvotes: 0

Views: 248

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36379

You need to use takeResult instead of result in order to use move only types.

QFuture isn't really designed with movable types in mind and you might be better off using a copyable type or std::future instead.

Upvotes: 1

Related Questions