1

I'd like to use Qt's mappedReduced with lambdas.

Answers to Make QtConcurrent::mapped work with lambdas seem to suggest that this is not possible directly, but might be achieved by use of std::function.

But while I can build a compiler-accepted call to mapped() this way, I cannot figure out how to apply the principle to mappedReduced() in a way that the compiler wants to compile. How must this be formulated?

Simple example:

    int cap = 1;
    std::function<int(char)> mlf = [cap](char c){ return static_cast<int>(c)+cap; };
    std::function<void(double&,int const&)> rlf = [cap](double &d,int const &i){ d += static_cast<double>(i+cap); };
    QVector<char> seq = {'a','b','c'};
    QVector<int> v = QtConcurrent::blockingMapped( seq, mlf );
    double d =  QtConcurrent::blockingMappedReduced( seq, mlf, rlf );

[NB: The final code has to support captures, therefore I included captures in this example. Removing the captures won't make to compiler happy here.]

The IDE/compiler complains:

qtsupplement.cpp:291:17: error: no matching function for call to 'blockingMappedReduced'
qtconcurrentmap.h:199:12: note: candidate template ignored: couldn't infer template argument 'ResultType'
qtconcurrentmap.h:213:65: note: candidate template ignored: substitution failure [with MapFunctor = std::function<int (char)>, ReduceFunctor = std::function<void (double &, const int &)>, Sequence = QVector<char>]: implicit instantiation of undefined template 'QtPrivate::ReduceResultType<std::function<void (double &, const int &)> >'
qtconcurrentmap.h:228:12: note: candidate function template not viable: requires at least 4 arguments, but 3 were provided
qtconcurrentmap.h:243:65: note: candidate function template not viable: requires at least 4 arguments, but 3 were provided

while the 'ResultType' should be the type of variable d and the first parameter of rlf() hints to the result type, too.

used versions: qt5.5.1, g++5.4.0, qtcreator4.9.0

kaba
  • 362
  • 1
  • 13

1 Answers1

1

The following code works for me (Qt 6.0.3, C++17):

int cap = 1;
QVector<char> seq = {'a','b','c'};
QVector<int> v = QtConcurrent::blockingMapped<QVector<int>>(
    seq,
    [cap](char c){ return static_cast<int>(c)+cap; }
);
double d = QtConcurrent::blockingMappedReduced<double>(
    seq,
    [cap](char c){ return static_cast<int>(c)+cap; },
    [cap](double &d,int const& i){ d += static_cast<double>(i+cap); }
);

So you should use Qt 6.0.3 and specify template arguments.

Roman Podymov
  • 4,168
  • 4
  • 30
  • 57