並行フィルタとフィルタ・リデュース
QtConcurrent::filter()、QtConcurrent::filtered()、QtConcurrent::filteredReduced() 関数は、QList のようなシーケンス内の項目を並列にフィルタリングします。QtConcurrent::filter() はシーケンスをインプレースで変更し、 QtConcurrent::filtered() はフィルタリングされた内容を含む新しいシーケンスを返し、 QtConcurrent::filteredReduced() は単一の結果を返します。
これらの関数は Qt Concurrentフレームワークの一部です。
上記の各関数には、QFuture の代わりに最終結果を返すブロッキング型があります。 非同期型と同じように使用します。
QStringList strings = ...; // each call blocks until the entire operation is finished QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strings, allLowerCase); QtConcurrent::blockingFilter(strings, allLowerCase); QSet<QString> dictionary = QtConcurrent::blockingFilteredReduced(strings, allLowerCase, addToDictionary);
上記の結果型はQFuture オブジェクトではなく、実際の結果型(この場合はQStringList とQSet<QString>)であることに注意してください。
並行フィルタ
QtConcurrent::filtered() は、入力シーケンスとフィルタ関数を受け取ります。このフィルタ関数は、シーケンスの各項目に対して呼び出され、フィルタリングされた値を含む新しいシーケンスが返されます。
フィルタ関数は
bool function(const T &t);
T はシーケンスに格納されている型と一致しなければならない。この関数は、アイテムが保持されるべきであればtrue
を返し、破棄されるべきであれば false を返します。
この例では、すべて小文字の文字列をQStringList から保持する方法を示す:
bool allLowerCase(const QString &string) { return string.lowered() == string; } QStringList strings = ...; QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings, allLowerCase);
フィルタの結果は、QFuture 。アプリケーションでQFuture を使用する方法の詳細については、QFuture とQFutureWatcher のドキュメントを参照してください。
インプレースでシーケンスを変更したい場合は、QtConcurrent::filter() を使用してください:
QStringList strings = ...; QFuture<void> future = QtConcurrent::filter(strings, allLowerCase);
シーケンスはその場で変更されるため、QtConcurrent::filter() はQFuture 経由では結果を返しません。しかし、QFuture とQFutureWatcher を使用して、フィルタの状態を監視することができます。
並行フィルタ-削減
QtConcurrent::filteredReduced() は、QtConcurrent::filtered() と似ていますが、フィルタリングされた結果のシーケンスを返す代わりに、reduce 関数を使用して結果を 1 つの値にまとめます。
reduce 関数は以下の形式でなければなりません:
V function(T &result, const U &intermediate)
T は最終結果の型、U はフィルタリングされる項目の型です。reduce 関数の戻り値と戻り値の型は使用されないことに注意してください。
次のように QtConcurrent::filteredReduced() を呼び出します:
void addToDictionary(QSet<QString> &dictionary, const QString &string) { dictionary.insert(string); } QStringList strings = ...; QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary);
reduce 関数は、フィルタ関数によって保持された各結果に対して 1 回呼び出され、中間値を結果変数にマージします。QtConcurrent::filteredReduced() は、一度に reduce を呼び出すスレッドが 1 つだけであることを保証しているので、結果変数をロックするためにミューテックスを使用する必要はありません。QtConcurrent::ReduceOptions enum は、リダクションを行う順序を制御する方法を提供します。
その他の API 機能
シーケンスの代わりにイテレータを使用する
上記の各関数には、シーケンスの代わりにイテレータを受け取るバリアントがあります。シーケンスのバリアントと同じように使用します:
QStringList strings = ...; QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings.constBegin(), strings.constEnd(), allLowerCase); // filter in-place only works on non-const iterators QFuture<void> future = QtConcurrent::filter(strings.begin(), strings.end(), allLowerCase); QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary);
メンバ関数の使用法
QtConcurrent::filter(), QtConcurrent::filtered(), QtConcurrent::filteredReduced() は、メンバ関数へのポインタを受け付けます。メンバ関数のクラス型は、シーケンスに格納されている型と一致する必要があります:
// アルファチャンネルを持つ画像のみを保持するQList<QImage>images= ...;QFuture<void>alphaImages=QtConcurrent::filter(images, &QImage::hasAlphaChannel);// グレイスケールの画像を取得します.QList<QImage>images= ...;QFuture<QImage>grayscaleImages=QtConcurrent::filtered(images, &QImage::isGrayscale);// 印刷可能な全ての文字の集合を作成する。QList<QChar> 文字= ...;QFuture<QSet<QChar>> セット QtConcurrent::filteredReduced(characters, qOverload<>(&QChar::isPrint)、 qOverload<const QChar&>(&QSet<QChar>::insert));
qOverloadこれは、複数のオーバーロードを持つメソッドの曖昧さを解消するために必要である。
また、QtConcurrent::filteredReduced() を使用する場合、通常の関数とメンバ関数を自由に混在させることができることに注意してください:
// QtConcurrent::filteredReduced() で、// 通常の関数とメンバ関数を混在させることができるextern boolallLowerCase(constQString文字列);QStringListstrings= ...;QFuture<QSet<QString>>lowerCase=QtConcurrent::filteredReduced(strings,allLowerCase、 qOverload<const QString&>(&QSet<QString>::insert)); // すべてのグレイスケール画像のコラージュを作成するextern voidaddToCollage(QImage &collage, const QImage &grayscaleImage);QList<QImage>images= ...;QFuture<QImage>コラージュ=QtConcurrent::filteredReduced(images, &QImage::isGrayscale,addToCollage);
関数オブジェクトの使用
QtConcurrent::filter(), QtConcurrent::filtered(), QtConcurrent::filteredReduced() は、フィルタ関数の関数オブジェクトを受け付けます。これらの関数オブジェクトは、関数呼び出しに状態を追加するために使用できます:
struct StartsWith { StartsWith(const QString &string) : m_string(string) { } bool operator()(const QString &testString) { return testString.startsWith(m_string); } QString m_string; }; QList<QString> strings = ...; QFuture<QString> fooString = QtConcurrent::filtered(strings, StartsWith(QLatin1String("Foo")));
関数オブジェクトは、reduce 関数でもサポートされています:
struct StringTransform { void operator()(QString &result, const QString &value); }; QFuture<QString> fooString = QtConcurrent::filteredReduced(strings, StartsWith(QLatin1String("Foo")), StringTransform());
ラムダ式の使用
QtConcurrent::filter()、 QtConcurrent::filtered()、 QtConcurrent::filteredReduced() は、 filter および reduce 関数にラムダ式を使用できます:
// keep only even integers QList<int> list { 1, 2, 3, 4 }; QtConcurrent::blockingFilter(list, [](int n) { return (n & 1) == 0; }); // retrieve only even integers QList<int> list2 { 1, 2, 3, 4 }; QFuture<int> future = QtConcurrent::filtered(list2, [](int x) { return (x & 1) == 0; }); QList<int> results = future.results(); // add up all even integers QList<int> list3 { 1, 2, 3, 4 }; QFuture<int> sum = QtConcurrent::filteredReduced(list3, [](int x) { return (x & 1) == 0; }, [](int &sum, int x) { sum += x; } );
QtConcurrent::filteredReduced() や QtConcurrent::blockingFilteredReduced() を使用する場合、通常の関数、メンバ関数、ラムダ式を自由に組み合わせて使用することができます。
void intSumReduce(int &sum, int x) { sum += x; } QList<int> list { 1, 2, 3, 4 }; QFuture<int> sum = QtConcurrent::filteredReduced(list, [] (int x) { return (x & 1) == 0; }, intSumReduce );
ラムダをリデュースオブジェクトとして渡すこともできます:
bool keepEvenIntegers(int x) { return (x & 1) == 0; } QList<int> list { 1, 2, 3, 4 }; QFuture<int> sum = QtConcurrent::filteredReduced(list, keepEvenIntegers, [](int &sum, int x) { sum += x; } );
複数の引数をとる関数のラッピング
複数の引数をとるフィルタ関数を使いたい場合は、ラムダ関数やstd::bind()
を使って、引数をひとつだけとる関数に変換することができます。
例として、QString::contains ()を使います:
bool QString::contains(const QRegularExpression ®exp) const;
QString::contains(なぜなら、QtConcurrent::filtered() は 1 つの引数を取る関数を想定しているからです。QtConcurrent::filtered()でQString::contains()を使用するには、正規表現引数の値を指定する必要があります:
QStringList strings = ...; QFuture<QString> future = QtConcurrent::filtered(list, [](const QString &str) { return str.contains(QRegularExpression("^\\S+$")); // matches strings without whitespace });
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.