std::function的实验

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
28
29
30
31
32
inline namespace function_use
{
int FuncB(int x, int y)
{
return x + y;
}

struct FuncC
{
int operator()(int x, int y)
{
return x + y;
}
};

void test_use_function()
{
using funcType = std::function<int(int, int)>;

funcType a = [](int x, int y) {
return x + y;
};

funcType b = FuncB;

funcType c = FuncC();

cout << "a = " << a(3, 4) << endl;
cout << "b = " << b(30, 40) << endl;
cout << "c = " << c(30, 4) << endl;
}
}

结果如下

a = 7
b = 70
c = 34


增加变化,加一个类如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class FuncContainer
{
public:
void Push(funcType&& func)
{
cout << "using void Push(funcType&& func)\n";
m_contianer.emplace_back(std::forward<funcType>(func));
}

void Push(funcType& func)
{
cout << "using void Push(funcType& func)\n";
m_contianer.emplace_back(func);
}

funcType& Take(int index)
{
cout << "using funcType& Take(int index)\n";
return m_contianer[index];
}
private:
vector<funcType> m_contianer;
};

测试方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void test_use_function()
{
FuncContainer container;
container.Push([](int x, int y) {
return x + y;
});
container.Push(FuncB);
container.Push(FuncC());
auto afunc = container.Take(0);
auto bfunc = container.Take(1);
auto cfunc = container.Take(2);
cout << "a = " << afunc(3, 4) << endl;
cout << "b = " << bfunc(30, 40) << endl;
cout << "c = " << cfunc(30, 4) << endl;
}

测试结果

using void Push(funcType&& func)
using void Push(funcType&& func)
using void Push(funcType&& func)
using funcType& Take(int index)
using funcType& Take(int index)
using funcType& Take(int index)
a = 7
b = 70
c = 34

实验结论

  1. std::function 作为通用的多态函数封装器, std::function 的实例能存储、复制及调用任何可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针
  2. std::function 配合using (或者typedef),可以用来作为容器的元素进行存储
  3. std::function 作为函数参数传递时,都是作为右值引用来进行传递的
  4. std::function 重载的 operator= 返回的是引用类型,所以,需要注意其存储元素的生命周期

参考:

std::function - C++中文 - API参考文档 (apiref.com)

http://note.youdao.com/noteshare?id=06b5f1b1fb45fa8bc1e478a1abf478eb&sub=978CCDA963334F62AAA7713154779E6E