C++ std::function、函数对象和lambda表达式

C++ std::function、函数对象和lambda表达式

std::function是C++11的新特性,包含在头文件

std::function类型对象可以包装函数指针、函数对象和lambda表达式

  1. 包装函数指针:
1
2
3
4
5
6
7
8
9
10
11
12
13
cppCopy code
#include <iostream>
#include <functional>

void func(int x) {
std::cout << "Function pointer: " << x << std::endl;
}

int main() {
std::function<void(int)> func_ptr = func;
func_ptr(10); // 调用包装的函数指针
return 0;
}
  1. 包装函数对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cppCopy code
#include <iostream>
#include <functional>

struct FuncObject {
void operator()(int x) {
std::cout << "Function object: " << x << std::endl;
}
};

int main() {
FuncObject obj;
std::function<void(int)> func_obj = obj;
func_obj(20); // 调用包装的函数对象
return 0;
}
  1. 包装lambda表达式:
1
2
3
4
5
6
7
8
9
10
11
12
13
cppCopy code
#include <iostream>
#include <functional>

int main() {
auto lambda = [](int x) {
std::cout << "Lambda expression: " << x << std::endl;
};

std::function<void(int)> func_lambda = lambda;
func_lambda(30); // 调用包装的lambda表达式
return 0;
}

std::function和std::bind一起使用

使用std::bind可以将可调用对象和参数一起绑定,绑定后的结果使用std::function进行保存,并延迟调用到任何我们需要的时候。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <functional>

class MyClass {
public:
void memberFunction(int a, int b) {
std::cout << "Member function called with arguments: " << a << " and " << b << std::endl;
}
};

void freeFunction(int a, int b) {
std::cout << "Free function called with arguments: " << a << " and " << b << std::endl;
}

int main() {
MyClass obj;

// 绑定成员函数到std::function对象
std::function<void(MyClass&, int, int)> memberFunctionBind = std::bind(&MyClass::memberFunction, &obj, std::placeholders::_1, std::placeholders::_2);
memberFunctionBind(10, 20);

// 绑定自由函数到std::function对象
std::function<void(int, int)> freeFunctionBind = std::bind(&freeFunction, std::placeholders::_1, std::placeholders::_2);
freeFunctionBind(30, 40);

return 0;
}

函数对象

C++中的函数对象(functors)是可以像函数一样被调用的对象,通常是类重载了函数调用操作符operator()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

// 定义一个函数对象类
class Adder {
public:
Adder(int num) : numToAdd(num) {}

int operator()(int x) const {
return x + numToAdd;
}

private:
int numToAdd;
};

int main() {
// 创建一个Adder函数对象
Adder add5(5);

// 使用函数对象
std::cout << "10 + 5 = " << add5(10) << std::endl;

return 0;
}

lambad表达式

Lambda表达式是一种函数对象

1
2
3
4
cppCopy code
[capture clause] (parameters) -> return_type {
// 函数体
}

- capture clause:捕获列表,用于指定Lambda表达式中可以使用的外部变量。可以是值传递、引用传递或隐式捕获。

- parameters:参数列表,与普通函数的参数列表类似。

- return_type:返回类型,与普通函数的返回类型类似。

- {}:函数体,包含Lambda表达式的具体实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main() {
int x = 10;
int y = 5;

auto sum = [x, y]() -> int {
return x + y;
};

std::cout << "Sum: " << sum() << std::endl;

return 0;
}
this捕获成员变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

class MyClass {
public:
MyClass(int value) : m_value(value) {}

void doSomething() {
int multiplier = 2;
auto lambda = [this, multiplier]() {
std::cout << "Member variable value: " << m_value << std::endl;
std::cout << "Multiplied value: " << m_value * multiplier << std::endl;
};

lambda();
}

private:
int m_value;
};

int main() {
MyClass obj(5);
obj.doSomething();

return 0;
}

ArkUI使用std::function举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
auto onAppear = [vm, func = panda::CopyableGlobal(vm, func), node = AceType::WeakClaim(frameNode), containerId]() {
panda::LocalScope pandaScope(vm);
panda::TryCatch trycatch(vm);
ContainerScope scope(containerId);
PipelineContext::SetCallBackNode(node);
func->Call(vm, func.ToLocal(), nullptr, 0);
};
NG::ViewAbstract::SetJSFrameNodeOnAppear(frameNode, std::move(onAppear));

void ViewAbstract::SetJSFrameNodeOnAppear(FrameNode* frameNode, std::function<void()>&& onAppear)
{
CHECK_NULL_VOID(frameNode);
auto eventHub = frameNode->GetEventHub<NG::EventHub>();
CHECK_NULL_VOID(eventHub);
eventHub->SetJSFrameNodeOnAppear(std::move(onAppear));
}

void EventHub::SetJSFrameNodeOnAppear(std::function<void()>&& onAppear)
{
onJSFrameNodeAppear_ = std::move(onAppear);
}

std::function<void()> onJSFrameNodeAppear_;