QT高级线程API总结(三)QtConcrrent::filter

目录

1、Header: #include

2、qmake: QT += concurrent

3、详细描述

4、number functions

4.1 QtConcurrent::filtered

4.2 QtConcurrent::filter

4.3 QtConcurrent::filteredReduced

4.4 QtConcurrent::blockingFilter

4.5 QtConcurrent::blockingFiltered

4.6 QtConcurrent::blockingFilteredReduced

5 API 附加特征

5.1 使用迭代器代替容器

5.2 使用成员函数

5.3 使用多个参数的函数


1、Header: #include <QtConcurrent>

2、qmake: QT += concurrent

3、详细描述

QtConcurrent::filter(), QtConcurrent::filtered()和QtConcurrent::filteredReduced()函数以一个序列(例如一个QList或一个QVector)并行地过滤项。

QtConcurrent::filter()在原地修改一个序列;

QtConcurrent::filtered()返回一个包含被过滤内容的新序列;

而QtConcurrent::filteredReduced()返回一个结果;

上面的每个函数都有一个阻塞变量,它返回最终结果results,而不是QFuture。可以与异步变体相同的方式使用它们。

QStringList strings = ...;

//每一次调用均阻塞,直到操作完成

QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strings, allLowerCase);

QtConcurrent::blockingFilter(strings, allLowerCase);

QSet<QString> dictionary = QtConcurrent::blockingFilteredReduced(strings, allLowerCase, addToDictionary);

注意,上面的结果类型不是QFuture对象,而是实际的结果类型(在本例中,QStringList和QSet<QString>)。

4、number functions

4.1 QtConcurrent::filtered

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()。

4.2 QtConcurrent::filter

QStringList strings = ...;

QFuture<void> future = QtConcurrent::filter(strings, allLowerCase);

由于序列是在适当的地方修改的,QtConcrrent::filter()不会通过QFuture返回任何结果。但是,仍然可以使用QFuture和QFutureWatcher来监视过滤器的状态。

4.3 QtConcurrent::filteredReduced

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

filter函数执行都将调用reduce(),并且应该将中间值合并到结果变量中。

QtConcurrent::filteredReduced()保证每次只有一个线程会调用reduce函数,所以没有必要使用互斥锁来锁定结果变量。QtConcurrent::ReduceOptions枚举类型可以控制其顺序。

4.4 QtConcurrent::blockingFilter

void QtConcurrent::blockingFilter(Sequence &sequence, FilterFunction filterFunction)

对容器中的每个项按顺序调用filterFunction一次。如果filterFunction返回true,则该项按顺序保存;否则,将从序列中删除该项。

注意:这个函数将阻塞直到序列中的所有项都被处理完。

4.5 QtConcurrent::blockingFiltered

Sequence QtConcurrent::blockingFiltered(const Sequence &sequence, FilterFunction filterFunction)

对容器中的每个项调用filterFunction一次,并返回保留项的新序列。如果filterFunction返回true,则该项的副本将被放入新的Sequence中。否则,该项目将不会出现在新的序列中。

注意:这个函数将阻塞直到序列中的所有项都被处理完。

Sequence QtConcurrent::blockingFiltered(ConstIterator begin, ConstIterator end, FilterFunction filterFunction)

从开始到结束对每个项调用filterFunction一次,并返回保留项的新序列。如果filterFunction返回true,则该项的副本将被放入新的Sequence中。否则,该项目将不会出现在新的序列中。

注意:这个函数将会阻塞,直到迭代器到达正在处理的序列的末尾。

4.6 QtConcurrent::blockingFilteredReduced

T QtConcurrent::blockingFilteredReduced(const Sequence &sequence, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)

对容器中每个项按顺序调用filterFunction函数一次。如果filterFunction为一个条目返回true,那么该条目将被传递给reduceFunction。换句话说,返回值是每个filterFunction返回true项的reduceFunction的结果。

注意,当filterFunction被并发调用时,每次只有一个线程会调用reduceFunction。如果reduceOptions为QtConcurrent::UnorderedReduce,那么reduceFunction的调用顺序是未定义的。如果reduceOptions为QtConcurrent::OrderedReduce,则reduceFunction将按原始顺序调用。

T QtConcurrent::blockingFilteredReduced(ConstIterator begin, ConstIterator end, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)

对容器中每个项按顺序调用filterFunction函数一次。如果filterFunction返回的时是true,那么该元素被保留并传递给reduceFunction函数。

注意,当filterFunction被并发调用的时候,每次只有一个线程会调用reduceFunction。如果reduceOptions 是QtConcurrent::UnorderedReduce,那么reduceFunction的调用顺序是未定义的。如果reduceOptions为QtConcurrent::OrderedReduce,则reduceFunction将按原始顺序调用。

5 API 附加特征

5.1 使用迭代器代替容器

上面的每个函数都有一个变量,接受迭代器范围而不是序列。你使用它们的方式与序列变体相同:

QStringList strings = ...;

QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings.constBegin(), strings.constEnd(), allLowerCase);

// 就地筛选只适用于非const迭代器

QFuture<void> future = QtConcurrent::filter(strings.begin(), strings.end(), allLowerCase);

QFuture<QSet<QString> > dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary);

5.2 使用成员函数

QtConcurrent::filter(), QtConcurrent::filtered()和QtConcurrent::filteredReduced()接受指向成员函数的指针。成员函数类类型必须匹配存储在序列中的类型:

// 只保留带有alpha通道的图像

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, &QChar::isPrint, &QSet<QChar>::insert);

注意,当使用QtConcurrent::filteredReduced()时,可以自由地混合使用普通函数和成员函数;

//可以使用QtConcurrent::filteredReduced()混合普通函数和成员函数

//创建一个所有小写字符串的字典

extern bool allLowerCase(const QString &string);

QStringList strings = ...;

QFuture<QSet<int> > averageWordLength = QtConcurrent::filteredReduced(strings, allLowerCase, 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()接受函数对象,这些对象可以用来为函数调用添加状态。result_type typedef必须定义函数调用操作符的结果类型:

struct StartsWith

{

      StartsWith(const QString &string): m_string(string) { }

       typedef bool result_type;

       bool operator()(const QString &testString)

       {

                  return testString.startsWith(m_string);

       }

      QString m_string;

};

QList<QString> strings = ...;

QFuture<QString> fooString = QtConcurrent::filtered(images, StartsWith(QLatin1String("Foo")));

5.3 使用多个参数的函数

如果您想要使用一个接受多个参数的筛选函数,您可以使用lambda函数或std::bind()将其转换为一个接受一个参数的函数。

例如,我们使用QString::contains():

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

QString::contains()接受2个参数(包括"this"指针),不能直接与QtConcurrent::filtered()一起使用,因为QtConcurrent::filtered()期望一个只有一个参数的函数。要在QtConcurrent::filtered()中使用QString::contains(),我们必须为regexp参数提供一个值:

QStringList strings = ...;

QFuture<QString> future = QtConcurrent::filtered(list, [](const QString &str) {

                return str.contains(QRegularExpression("^\\S+$")); // matches strings without whitespace

});

 

 

 

 

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值