QtConcurrent error: attempting to reference a deleted function

QtConcurrent error: attempting to reference a deleted function

我想 运行 在与 Qt 应用程序内的 GUI 线程不同的线程中使用简单方法。为此,我使用 QFuture and Qt Concurrent。然而,我运行进入编译错误:

C:\Qt.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentstoredfunctioncall.h(58): error C2280: 'QtConcurrent::RunFunctionTask<T>::RunFunctionTask(void)': attempting to reference a deleted function
        with
        [
            T=Error
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentrunbase.h(121): note: compiler has generated 'QtConcurrent::RunFunctionTask<T>::RunFunctionTask' here
        with
        [
            T=Error
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentrunbase.h(121): note: 'QtConcurrent::RunFunctionTask<T>::RunFunctionTask(void)': function was implicitly deleted because a data member 'QtConcurrent::RunFunctionTask<T>::result' has either no appropriate default constructor or overload resolution was ambiguous
        with
        [
            T=Error
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentrunbase.h(120): note: see declaration of 'QtConcurrent::RunFunctionTask<T>::result'
        with
        [
            T=Error
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentstoredfunctioncall.h(58): note: while compiling class template member function 'QtConcurrent::StoredFunctorCall0<T,T (__cdecl *)(void)>::StoredFunctorCall0(FunctionPointer)'
        with
        [
            T=Error,
            FunctionPointer=Error (__cdecl *)(void)
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent\qtconcurrentrun.h(74): note: see reference to function template instantiation 'QtConcurrent::StoredFunctorCall0<T,T (__cdecl *)(void)>::StoredFunctorCall0(FunctionPointer)' being compiled
        with
        [
            T=Error,
            FunctionPointer=Error (__cdecl *)(void)
        ]
C:\Qt.15.2\msvc2019_64\include\QtConcurrent\qtconcurrentrun.h(74): note: see reference to class template instantiation 'QtConcurrent::StoredFunctorCall0<T,T (__cdecl *)(void)>' being compiled
        with
        [
            T=Error
        ]
C:\Users\dalji\Documents\Dev\TestQtConcurrent\main.cpp(37): note: see reference to function template instantiation 'QFuture<Error> QtConcurrent::run<Error>(T (__cdecl *)(void))' being compiled
        with
        [
            T=Error
        ]
ninja: build stopped: subcommand failed.
16:14:59: The process "C:\Qt\Tools\CMake_64\bin\cmake.exe" exited with code 1.
Error while building/deploying project TestQtConcurrent (kit: Desktop Qt 5.15.2 MSVC2019 64bit)
When executing step "Build"

这是一个简单的测试应用程序,可以重现我遇到的问题

#include <QCoreApplication>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>

class Error
{
public:
    enum class ErrorType {
        NoError,
        FileSavingError,
        FileLoadingError
    };
    Error(ErrorType errorType, const QString &errorMessage  = "") :
        m_errorType(errorType),
        m_errorMessage(errorMessage)
    {

    }
    const QString &errorMessage() const { return m_errorMessage; }
    ErrorType errorType() const {  return m_errorType; }

private:
    ErrorType m_errorType;
    QString m_errorMessage;
};


Error testMethod(){
    return Error(Error::ErrorType::NoError, "No Error");
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFuture<Error> errorFuture = QtConcurrent::run(testMethod);
    return a.exec();
}

我做错了什么?

如评论中所述以及错误消息本身所示,问题是您的 Error class 没有默认构造函数。

虽然 documentation for QtConcurrentRun that indicates this requirement, there is the following in the documentation for QFuture 中没有任何明确的内容(大胆强调我的)1:

QFuture allows threads to be synchronized against one or more results which will be ready at a later point in time. The result can be of any type that has a default constructor and a copy constructor. …

将所需的默认构造函数添加到 Error class 的最简单方法是在 currently-defined 构造函数(我假设 ErrorType::NoError 枚举是此默认值的合理值):

    Error(ErrorType errorType = ErrorType::NoError, const QString& errorMessage = "") :
        m_errorType(errorType),
        m_errorMessage(errorMessage)
    {
    }

1 请注意,对于您的 Error class,(也是必需的)copy constructor is implicitly declared 和将为您生成,通过编译器。