Sharethefun
Sharethefun

Reputation: 824

argument of type 'void (ClassName::)(QString&)' does not match 'void (ClassName::*)(QString&)'

Im trying to use Qt's qtconcurrentmap to process some images and I'm getting the following error

argument of type 'void (ClassName::)(QString&)' does not match 'void (ClassName::*)(QString&)

I'm also getting

/Library/Frameworks/QtCore.framework/Headers/qtconcurrentmapkernel.h:: 
In member function 'bool QtConcurrent::MapKernel<Iterator, MapFunctor>::runIteration(Iterator, int, void*) 
[with Iterator = QList<QString>::iterator, MapFunctor = void (ClassName::*)(QString&)]':


/Library/Frameworks/QtCore.framework/Headers/qtconcurrentmapkernel.h:73: 
error: must use '.*' or '->*' to call pointer-to-member function in 
'((QtConcurrent::MapKernel<QList<QString>::iterator, void (ClassName::*)(QString&)>*)this)->QtConcurrent::MapKernel<QList<QString>::iterator, void (ClassName::*)(QString&)>::map (...)'

This is my code

void ClassName::processImage(QString &f)
{

    Image image;
        image.read(qPrintable(f));
        try {
            //Apply effects on an Image
        } catch ( Magick::Exception & error) {
            // Displaying any possible errors on the text browser
            ui->textBrowser_error->setText(error.what());

        }
}



void ClassName::processAll() {

    foreach (QFileInfo f, list)
     {      QString str(f.absoluteFilePath());
            QList<QString> listof;
            listof.append(str);
     }


    QFuture<void> future = QtConcurrent::map(listof, processImage);
}

Any Ideas?

Upvotes: 0

Views: 1588

Answers (3)

Diego Sevilla
Diego Sevilla

Reputation: 29021

Two things here. First, the variable listof is declared inside the foreach loop, so it may not be visible at the point of creating future. Second, you should use &ClassName::processImage as the second parameter to QtConcurrent::map().

UPDATE:

Looking at the documentation, it seems you need to write the call to create the map this way:

QFuture<void> future = QtConcurrent::map(listof, boost::bind(&ClassName::processImage, this));

(you have to use boost.bind to convert a member function into a normal function, that is what map expect as the second argument).

Upvotes: 7

Frank Osterfeld
Frank Osterfeld

Reputation: 25165

About the second error: You can't pass a non-static member function like this. map() wouldn't know which object to call it on (which must be of type ClassName).

From QtConcurrentMap docs:

QtConcurrent::map(), QtConcurrent::mapped(), and QtConcurrent::mappedReduced() accept pointers to member functions. The member function class type must match the type stored in the sequence: "

You pass a QString list, but the member function is from ClassName. You can achieve something like this with boost::bind (and probably also with some mem_fun/bind1st-fu from the STL):

...map( listof, boost::bind( &ClassName::processImage, this, _1 ) );

Still this won't work as you can't call QTextEdit::setText() from other threads than the UI thread.

Also, it should be processImage(const QString&) instead of processImage(QString&).

Upvotes: 1

Mark B
Mark B

Reputation: 96281

I think it's taking a function instead of a function address.

QFuture<void> future = QtConcurrent::map(listof, &ClassName::processImage);

Upvotes: 1

Related Questions