2017-05-01 2 views
2

QtConcurrent::mappedQVector<QString>に使用しようとしています。私はすでに多くの方法を試しましたが、オーバーロードには常に問題があるようです。QtConcurrent :: mapsをlambdaで作成する

QVector<QString> words = {"one", "two", "three", "four"}; 

using StrDouble = std::pair<QString, double>; 

QFuture<StrDouble> result = QtConcurrent::mapped<StrDouble>(words, [](const QString& word) -> StrDouble { 
    return std::make_pair(word + word, 10); 
}); 

このスニペットは、次のエラーを返します。

/home/lhahn/dev/cpp/TestLambdaConcurrent/mainwindow.cpp:23: error: no matching function for call to ‘mapped(QVector<QString>&, MainWindow::MainWindow(QWidget*)::<lambda(const QString&)>)’ 
}); 
^

私はQtは、ラムダの戻り値を見つけることができないと言われ、このpostを見たので、あなたはそれでstd::bindを使用する必要があります。私はこのしようとした場合:

using StrDouble = std::pair<QString, double>; 
using std::placeholders::_1; 

auto map_fn = [](const QString& word) -> StrDouble { 
    return std::make_pair(word + word, 10.0); 
}; 

auto wrapper_map_fn = std::bind(map_fn, _1); 

QFuture<StrDouble> result = QtConcurrent::mapped<StrDouble>(words, wrapper_map_fn); 

しかし、それでもエラーが似ています。

/home/lhahn/dev/cpp/TestLambdaConcurrent/mainwindow.cpp:28: error: no matching function for call to ‘mapped(QVector<QString>&, std::_Bind<MainWindow::MainWindow(QWidget*)::<lambda(const QString&)>(std::_Placeholder<1>)>&)’ 
QFuture<StrDouble> result = QtConcurrent::mapped<StrDouble>(words, wrapper_map_fn); 
                       ^

私もstd::function内部ラムダが、残念ながら、同様の結果をラップしてみました。

  • この例は再現のためのものであり、コード内に変数を取り込むため、ラムダが必要です。
+0

どうやら、QtConcurrentとしてラムダまだ...をサポートしていません。私がソースから読むことができる限り、関数ポインタやメンバ関数ポインタが必要です:https://github.com/qt/qtbase/blob/dev/src/concurrent/qtconcurrentfunctionwrappers.h – Felix

答えて

2

私のために、次のコンパイル:qDebug() << result.results()

QVector<QString> words = {"one", "two", "three", "four"}; 
std::function<StrDouble(const QString& word)> func = [](const QString &word) { 
    return std::make_pair(word + word, 10.0); 
}; 

QFuture<StrDouble> result = QtConcurrent::mapped(words, func); 

が出力:残念ながら

(std::pair("oneone",10), std::pair("twotwo",10), std::pair("threethree",10), std::pair("fourfour",10))

+0

キャプチャリストに何もないために動作します。 QtConcurrentはキャプチャを伴うラムダ関数では機能しません。 – benlau

+1

正しい:私はQtConcurrent :: mappedがラムダ関数でキャプチャで動作しないことを意味する – benlau

0

QtConcurrent ::マップされたが、キャプチャとラムダ関数をサポートしていないこと。カスタム実装が必要な場合があります。たとえば、AsyncFutureでものを作ることがあります。

template <typename T, typename Sequence, typename Functor> 
QFuture<T> mapped(Sequence input, Functor func){ 
    auto defer = AsyncFuture::deferred<T>(); 

    QList<QFuture<T>> futures; 
    auto combinator = AsyncFuture::combine(); 

    for (int i = 0 ; i < input.size() ; i++) { 
     auto future = QtConcurrent::run(func, input[i]); 
     combinator << future; 
     futures << future; 
    } 

    AsyncFuture::observe(combinator.future()).subscribe([=]() { 
     QList<T> res; 
     for (int i = 0 ; i < futures.size(); i++) { 
      res << futures[i].result(); 
     } 
     auto d = defer; 
     d.complete(res); 
    }); 

    return defer.future(); 
} 

使用法:

auto future = mapped<int>(input, func); 

完全な例:

https://github.com/benlau/asyncfuture/blob/master/tests/asyncfutureunittests/example.cpp#L326

関連する問題