Home > other >  QtConcurrent error: attempting to reference a deleted function
QtConcurrent error: attempting to reference a deleted function

Time:02-28

I'd like to run simple method in a different thread than the GUI thread inside my Qt application. To do this I'm using QFuture and Qt Concurrent. However, I ran into a compile error:

C:\Qt\5.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\5.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentrunbase.h(121): note: compiler has generated 'QtConcurrent::RunFunctionTask<T>::RunFunctionTask' here
        with
        [
            T=Error
        ]
C:\Qt\5.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\5.15.2\msvc2019_64\include\QtConcurrent/qtconcurrentrunbase.h(120): note: see declaration of 'QtConcurrent::RunFunctionTask<T>::result'
        with
        [
            T=Error
        ]
C:\Qt\5.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\5.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\5.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"

Here is a simple test application that reproduces the issue I'm having

#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();
}

What am I doing wrong?

CodePudding user response:

As noted in the comments, and as indicated in the error message itself, the problem is that your Error class has no default constructor.

While there is nothing explicit in the documentation for QtConcurrentRun that indicates this requirement, there is the following in the documentation for QFuture (bold emphasis mine)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. …

The simplest way to add the required default constructor to your Error class is to add a default value for the first argument (you already have one for the second argument) in your currently-defined constructor (I've assumed that the ErrorType::NoError enumeration is a sensible value for this default):

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

1 Note that, for your Error class, the (also required) copy constructor is implicitly declared and will be generated for you, by the compiler.

  • Related