並行フィルタおよびフィルタ・リデュース
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> ヘッダーをインクルードすると、Qt Concurrent モジュール全体とQt Core モジュール全体がインクルードされるため、コンパイル時間やバイナリサイズが増加する可能性があります。QtConcurrent::filter()、QtConcurrent::filtered()、およびQtConcurrent::filteredReduced()関数を使用するには、より具体的なヘッダーをインクルードすることができます:
#include <QtConcurrentFilter>並行フィルタ
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::filtered() の呼び出し結果は、複数の結果を含むQFuture です。このようなQFuture に.then() 継続をアタッチする際は、必ずQFuture をパラメータとして受け取る継続を使用してください。そうしないと、最初の結果のみが処理されます:
autokeepPositive= [](intval) {
returnval> 0;
};
QList<int>inputs {-1, 1, 2,-3, 5};
autobadFuture=QtConcurrent::filtered(inputs,keepPositive)
.then([](intval) {
qDebug() << val;
});
autogoodFuture=QtConcurrent::filtered(inputs,keepPositive)
.then([](QFuture<int>f) {
for(autor : f.results()) {
qDebug() << r;
}
});この例では、badFuture は 1 つの結果のみを出力しますが、goodFuture はすべての結果を出力します。
並行フィルタ・リデュース
QtConcurrent::filteredReduced() は QtConcurrent::filtered() と似ていますが、フィルタリングされた結果を含むシーケンスを返す代わりに、リデュース関数を使用して結果を単一の値に結合します。
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関数は、filter関数によって保持された結果ごとに1回呼び出され、中間結果をresult変数に統合する必要があります。QtConcurrent::filteredReduced()は、一度に1つのスレッドのみがreduceを呼び出すことを保証しているため、result変数をロックするためにミューテックスを使用する必要はありません。QtConcurrent::ReduceOptions 列挙型を使用することで、縮小処理が行われる順序を制御することができます。
その他のAPI機能
Sequenceの代わりにイテレータを使用する
上記の各関数には、シーケンスの代わりにイテレータ範囲を受け取るバリエーションがあります。これらは、シーケンスを受け取るバリエーションと同じように使用します:
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>characters=...;
QFuture<QSet<QChar>>set=QtConcurrent::filteredReduced(characters, qOverload<>(&QChar::isPrint),
qOverload<const QChar&>(&QSet<QChar>::insert));qOverload の使用に注意してください。これは、複数のオーバーロードを持つメソッドの曖昧さを解消するために必要です。
また、QtConcurrent::filteredReduced() を使用する際は、通常の関数とメンバ関数を自由に組み合わせて使用できる点にも注意してください:
// QtConcurrent::filteredReduced() では、通常の関数とメンバ関数を混在させることができます
// すべて小文字に変換された文字列の辞書を作成する
extern boolallLowerCase(constQString&string);
QStringList strings=...;
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() を使用して、それを1つの引数を取る関数に変換することができます。
例として、QString::contains() を使用します:
bool QString::contains(const QRegularExpression ®exp) const;QString::contains() は 2 つの引数(「this」ポインタを含む)を受け取りますが、QtConcurrent::filtered() は引数を 1 つだけ受け取る関数を期待しているため、この関数を QtConcurrent::filtered() と直接併用することはできません。QString::contains() を QtConcurrent::filtered() と一緒に使用するには、regexp引数に値を指定する必要があります:
QStringList strings = ...;
QFuture<QString> future = QtConcurrent::filtered(list, [](const QString &str) {
return str.contains(QRegularExpression("^\\S+$")); // matches strings without whitespace
});© 2026 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.