目录
匿名函数
qt中有匿名函数,就是lambda函数参考 跳转
回调函数
回调函数的表现方式有几种:
函数指针
qt 中void*
作为回调函数
在Qt中,你可以使用函数指针作为回调函数。这里有一个简单的例子,展示了如何使用void*
作为回调函数的参数。
#include <QObject>
#include <QDebug>
class MyClass : public QObject {
Q_OBJECT
public:
using Callback = void(*)(void*);
MyClass(QObject *parent = nullptr) : QObject(parent) {}
void registerCallback(Callback callback, void* userData) {
// 保存回调函数和用户数据
m_callback = callback;
m_userData = userData;
}
void triggerCallback() {
if (m_callback) {
// 调用回调函数
m_callback(m_userData);
}
}
private:
Callback m_callback = nullptr;
void* m_userData = nullptr;
};
// 回调函数示例
void myCallback(void* userData) {
qDebug() << "Callback called with user data:" << userData;
}
int main() {
MyClass obj;
// 注册回调函数
obj.registerCallback(myCallback, (void*)"Hello World");
// 触发回调
obj.triggerCallback();
return 0;
}
std::function
qt std::function传参
在Qt中,std::function是一种通用的多态函数封装。它可以容纳各种可调用对象,包括函数、lambda表达式、bind表达式等。你可以使用std::function来传递参数给Qt的信号和槽机制。
以下是一个简单的例子,演示如何使用std::function作为Qt的槽函数:
#include <QObject>
#include <functional>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent = nullptr) : QObject(parent) {}
signals:
void mySignal(int param);
public slots:
void mySlot(int param);
};
void MyClass::mySlot(int param)
{
// 处理param
}
int main()
{
MyClass obj;
std::function<void(int)> func = std::bind(&MyClass::mySlot, &obj, std::placeholders::_1);
QObject::connect(&obj, &MyClass::mySignal, &func);
// 当发送mySignal时,会调用mySlot
emit obj.mySignal(42);
return 0;
}
lambda转函数指针与std::funtion
参考跳转
将 Lambda 表达式转换为函数指针
要将 Lambda 表达式转换为函数指针,有几个重要的注意事项:
- Lambda 必须没有捕获(Capture):即捕获列表必须为空 [ ]。只有没有捕获的 lambda 表达式(纯函数)才能转换为函数指针。
- 显式指定函数签名:对于转换为函数指针的情况,lambda 表达式的参数和返回类型需要显式指定。
#include <iostream>
// 定义一个不捕获变量的 lambda
auto lambda = [](int a, int b) -> int {
return a + b;
};
// 将 lambda 转换为函数指针
int (*func_ptr)(int, int) = lambda;
int main() {
// 使用函数指针调用 lambda 表达式
std::cout << func_ptr(3, 4) << std::endl; // 输出 7
return 0;
}
lambda 表达式转换std::function
如果 lambda 表达式有捕获,只能使用 std::function 来存储它。这是因为带捕获的 lambda 需要存储额外的状态,不能直接转换为普通函数指针。
示例
#include <iostream>
#include <functional>
int main() {
// 定义一个捕获变量的 lambda
int factor = 10;
auto lambda = [factor](int x) -> int {
return x * factor;
};
// 使用 std::function 存储带捕获的 lambda
std::function<int(int)> func = lambda;
// 使用调用
std::cout << func(5) << std::endl; // 输出 50
return 0;
}
虽然你不能将带捕获的 lambda 直接转换为普通函数指针,std::function 提供了一个灵活的和类型安全的方式来存储和调用带捕获的 lambda。
通用 lambda 和自动返回类型
在 C++14 和之后的标准中,引入了一些新特性,如通用 lambda 和自动返回类型,这使得 lambda 表达式的使用变得更加广泛和灵活。
#include <iostream>
#include <functional>
int main() {
// 定义一个通用 lambda,可以接受任何类型的参数
auto generic_lambda = [](auto x, auto y) {
return x + y;
};
// 使用 std::function 存储通用 lambda
std::function<int(int, int)> func = generic_lambda;
// 使用调用
std::cout << func(3, 4) << std::endl; // 输出 7
// 直接使用 lambda
std::cout << generic_lambda(1.5, 2.7) << std::endl; // 输出 4.2
return 0;
}
总结
需要捕获就要使用std::function
其他情况可以