이 페이지에서

병렬 필터 및 필터-리듀스

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 를 매개변수로 받는 연속체를 사용해야 합니다. 그렇지 않으면 첫 번째 결과만 처리됩니다:

auto keepPositive = [](int val) {
    return val > 0;
};

QList<int> inputs {-1, 1, 2,-3, 5 };
auto badFuture = QtConcurrent::filtered(inputs, keepPositive)
                         .then([](int val) {
                             qDebug() << val;
                         });

auto goodFuture = QtConcurrent::filtered(inputs, keepPositive)
                          .then([](QFuture<int> f) {
                              for (auto r : f.results()) {
                                  qDebug() << r;
                              }
                          });

이 예제에서 badFuture 는 단 하나의 결과만 출력하는 반면, goodFuture 는 모든 결과를 출력합니다.

병렬 필터-리듀스

QtConcurrent::filteredReduced()는 QtConcurrent::filtered()와 유사하지만, 필터링된 결과를 포함하는 시퀀스를 반환하는 대신 리듀스 함수를 사용하여 결과를 단일 값으로 결합합니다.

리듀스 함수는 다음 형식을 따라야 합니다:

V function(T &result, const U &intermediate)

여기서 T는 최종 결과의 유형이고, U는 필터링되는 항목의 유형입니다. 리듀스 함수의 반환 값과 반환 유형은 사용되지 않는다는 점에 유의하십시오.

다음과 같이 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 함수가 유지한 각 결과에 대해 한 번씩 호출되며, 중간 결과를 result 변수에 병합해야 합니다. QtConcurrent::filteredReduced()는 한 번에 하나의 스레드만 reduce를 호출하도록 보장하므로, result 변수를 잠그기 위해 뮤텍스를 사용할 필요가 없습니다. QtConcurrent::ReduceOptions 열거형은 축소 연산이 수행되는 순서를 제어하는 방법을 제공합니다.

추가 API 기능

Sequence 대신 Iterator 사용

위의 각 함수에는 시퀀스 대신 이터레이터 범위를 인수로 받는 변형이 있습니다. 이 변형들은 시퀀스 변형과 동일한 방식으로 사용합니다:

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 bool allLowerCase(const QString&string);
QStringList strings =...;
QFuture<QSet<QString>> lowerCase = QtConcurrent::filteredReduced(strings, allLowerCase,
                                                                 qOverload<const QString&>(&QSet<QString>::insert));

// 모든 그레이스케일 이미지로 콜라주 만들기
extern void addToCollage(QImage &collage, const QImage &grayscaleImage);
QList<QImage> images =...;
QFuture<QImage> collage = 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")));

리듀스 함수에서도 함수 객체를 사용할 수 있습니다:

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
);

또한 람다를 reduce 객체로 전달할 수도 있습니다:

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;
    }
);

여러 인자를 받는 함수 래핑하기

인수가 두 개 이상인 filter 함수를 사용하려면, 람다 함수나 std::bind() 를 사용하여 인수가 하나인 함수로 변환할 수 있습니다.

예를 들어, QString::contains()를 사용해 보겠습니다:

bool QString::contains(const QRegularExpression &regexp) const;

QString::contains()는 2개의 인자(‘this’ 포인터 포함)를 받으며, QtConcurrent::filtered()는 하나의 인자를 받는 함수를 기대하기 때문에 이 함수를 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.