看看Qt里那些使用了匿名函数

匿名函数也可以被叫做Lambda表达式,自C++11中引入该特性。本文主要介绍Qt里使用到的匿名函数。

插图

1. connect中使用

  • connect中可以使用匿名函数代替槽函数进行一些简单操作。
  • 原型

    1
    2
    3
    4
    5
    6
    7
    //connect to a functor
    template <typename Func1, typename Func2>
    static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::type
    connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
    {
    return connect(sender, signal, sender, std::move(slot), Qt::DirectConnection);
    }
  • 示例

    1
    2
    3
    4
    QPushButton *button = new QPushButton;
    connect(button, &QPushButton::clicked, [this]() {
    ...
    });

2. 排序使用

  • 原型

    1
    2
    3
    4
    5
    6
    template <typename RandomAccessIterator, typename LessThan>
    QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
    {
    if (start != end)
    QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
    }
  • 使用

    1
    2
    3
    4
    5
    6
    7
    QList<int> list{3, 1, 2};
    qSort(list.begin(),
    list.end(),
    [](int left, int right)->bool {
    return left < right;
    }
    );

3. 高级线程中使用

  • QtConcurrent命名空间中的run接口支持匿名函数,用起来简直爽得不要不要的。
  • 原型

    1
    2
    3
    4
    5
    template <typename T>
    QFuture<T> run(T (*functionPointer)())
    {
    return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start();
    }
  • 使用

    1
    2
    3
    QtConcurrent::run([=](){
    ...
    });

4. 定时器中使用

  • QTimer的singleShot也支持匿名函数,用起来直观明了。
  • 原型

    1
    void singleShot(int msec, Functor functor)
  • 使用

    1
    2
    3
    QTimer::singleShot(1000, [](){
    qDebug()<<"Finished!!!";
    });

5. 与QVariant结合使用

  • 这个功能基本不会用到,楞是要找出一个用法可以看下Qt君往期推送的Qt网络开源库系列篇中有用到。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Q_DECLARE_METATYPE(std::function<void ()>)

    int main(int argc, char *argv[])
    {
    std::function<void ()> f = [](){ qDebug()<<"22"; };
    QVariant var = QVariant::fromValue(f);
    if (var.canConvert<std::function<void ()> >()) {
    std::function<void ()> func = var.value<std::function<void ()>>();
    func();
    }
    }

6. std::for_each

  • 原型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<class InputIterator, class Function>
    Function for_each(InputIterator first, InputIterator last, Function fn)
    {
    while (first!=last) {
    fn (*first);
    ++first;
    }
    return fn; // or, since C++11: return move(fn);
    }
  • 示例

    1
    2
    3
    4
    5
    6
    QList<int> list{1, 2, 3};
    std::for_each(list.begin(),
    list.end(),
    [](int i) {
    ...
    });

关于Qt中更多的匿名函数(Lambda表达式)写法也可以在留言区一起讨论