本文假设了解 boost::function 相关用法
首先需要包含的头文件为 boost/function.hpp
里面内容比较简单
1
2
3
4
5
6
7
8
9
10
11
|
# if BOOST_FUNCTION_MAX_ARGS >= 0
# include <boost/function/function0.hpp>
# endif
# if BOOST_FUNCTION_MAX_ARGS >= 1
# include <boost/function/function1.hpp>
# endif
# if BOOST_FUNCTION_MAX_ARGS >= 2
# include <boost/function/function2.hpp>
# endif
# if BOOST_FUNCTION_MAX_ARGS >= 3
# include <boost/function/function3.hpp>
# endif
... ...
|
默认的 BOOST_FUNCTION_MAX_ARGS 为 10,说明最大支持为10个参数
那么,可以知道引入了function0 ~ function10 共11个文件
第N个文件都是定义了支持 N 个参数的 function 类
我们以参数 BOOST_FUNCTION_MAX_ARGS = 4 来看看定义
boost/function/function4.hpp 头文件里只有这样几行
1
2
3
|
#define BOOST_FUNCTION_NUM_ARGS 4
#include <boost/function/detail/maybe_include.hpp>
#undef BOOST_FUNCTION_NUM_ARGS
|
boost/function/detail/maybe_include.hpp 里面其实就定义了 BOOST_FUNCTION_N
1
2
3
4
5
6
7
8
9
10
11
12
|
#if BOOST_FUNCTION_NUM_ARGS == 0
# ifndef BOOST_FUNCTION_0
# define BOOST_FUNCTION_0
# include <boost/function/function_template.hpp>
# endif
#elif BOOST_FUNCTION_NUM_ARGS == 1
# ifndef BOOST_FUNCTION_1
# define BOOST_FUNCTION_1
# include <boost/function/function_template.hpp>
# endif
#elif BOOST_FUNCTION_NUM_ARGS == 2
# ifndef BOOST_FUNCTION_2
# define BOOST_FUNCTION_2
# include <boost/function/function_template.hpp>
# endif
... ...
|
boost/function/function_template.hpp 首先看两个宏定义
1
2
|
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
|
BOOST_FUNCTION_NUM_ARGS 就是当前文件支持的参数个数,当前是4 BOOST_FUNCTION_TEMPLATE_PARMS 是宏自身扩展,展开时可能如下:
1
2
3
4
|
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
// typename T0 , typename T1 , typename T2 , typename T3
// 同样 BOOST_FUNCTION_TEMPLATE_ARGS 展开如下
// T0 , T1 , T2 , T3
|
可以看到,我们用宏展开后的结果,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
33
34
|
template<typename R , typename T0 , typename T1 , typename T2 , typename T3>
class function<R ( T0 , T1 , T2 , T3)> : public function4<R , T0 , T1 , T2 , T3> {
typedef function4<R , T0 , T1 , T2 , T3> base_type;
typedef function self_type;
struct clear_type {};
public:
function() : base_type() {}
// 模板的 sfinae 原则,避免整数被选入
template<typename Functor>
function(Functor f,
typename enable_if_c<
(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value),
int>::type = 0) : base_type(f) {}
template<typename Functor,typename Allocator>
// 同上
function(Functor f, Allocator a,
typename enable_if_c<(
boost::type_traits::ice_not<(
is_integral<Functor>::value)>::value),int>::type = 0) :
base_type(f,a) {}
function(clear_type*) : base_type() {}
function(const self_type& f) : base_type(static_cast<const base_type&>(f)) {}
function(const base_type& f) : base_type(static_cast<const base_type&>(f)) {}
self_type& operator=(const self_type& f) {
self_type(f).swap(*this);
return *this;
}
template<typename Functor>
typename enable_if_c<(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value),
self_type&>::type
operator=(Functor f) {
self_type(f).swap(*this);
return *this;
}
self_type& operator=(clear_type*) {
this->clear();
return *this;
}
self_type& operator=(const base_type& f) {
self_type(f).swap(*this);
return *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
27
28
29
30
31
32
33
34
35
|
template<typename R , typename T0 , typename T1 , typename T2 , typename T3>
class function4 : public function_base
{
public:
typedef R result_type;
typedef boost::detail::function::basic_vtable4<R , T0 , T1 , T2 , T3> vtable_type;
struct clear_type {};
template<typename Functor>
function4(Functor f,
typename enable_if_c<(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value), int>::type = 0) {
this->assign_to(f);
}
// 主要赋值在这个函数
template<typename Functor>
void assign_to(Functor f) {
using detail::function::vtable_base;
// 以下两行是得到 Functor 的类型
// 这个是由 tag 做萃取器的
typedef typename detail::function::get_function_tag<Functor>::type tag;
typedef detail::function::get_invoker4<tag> get_invoker;
typedef typename handler_type::invoker_type invoker_type;
typedef typename get_invoker::template apply<Functor, R ,T0 , T1 , T2 , T3> handler_type;
// vtable_type 负责实际 Functor 映射到内部 function_buffer 的管理
// 这里之所以用静态的是因为同一种类型的 assign_to都是一样的策略
// 不同 Functor 自然生成不同的 assign_to,那么 stored_vtable 也自然不同了
static vtable_type stored_vtable =
{ { &manager_type::manage }, &invoker_type::invoke };
if (stored_vtable.assign_to(f, functor)) {
std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
if (boost::has_trivial_copy_constructor<Functor>::value &&
boost::has_trivial_destructor<Functor>::value &&
detail::function::function_allows_small_object_optimization<Functor>::value) {
value |= (std::size_t)0x01;
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
} else {
vtable = 0;
}
}
}
... ...
}
|
上面看有两个成员变量是比较重要的,一个是 vtable, 一个是 function
他们都在基类 function_base 中被描述
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
|
class function_base {
... ...
detail::function::vtable_base* vtable;
// 真正存储的指针
mutable detail::function::function_buffer functor;
};
union function_buffer {
mutable void* obj_ptr; // 对象指针类型
mutable void (*func_ptr)(); // 函数指针类型
// 指针本身的类型, 比如是const约束? volite约束?
struct type_t {
const detail::sp_typeinfo* type;
bool const_qualified;
bool volatile_qualified;
} type;
// 成员函数指针的结构
struct bound_memfunc_ptr_t {
void (X::*memfunc_ptr)(int);
void* obj_ptr;
} bound_memfunc_ptr;
// 对象引用类型
struct obj_ref_t {
mutable void* obj_ptr;
bool is_const_qualified;
bool is_volatile_qualified;
} obj_ref;
// 小函数对象的优化
// 如果是小函数对象,那么直接构造在这个 union 上
mutable char data;
};
// 这个是干嘛用的现在还不清楚
struct vtable_base {
void (*manager)(const function_buffer& in_buffer,
function_buffer& out_buffer,
functor_manager_operation_type op);
};
|
萃取器的 tag 代码如下
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
struct function_ptr_tag {};
struct function_obj_tag {};
struct member_ptr_tag {};
struct function_obj_ref_tag {};
template<typename F>
class get_function_tag {
// 这是个依次迭代的关系
// 巧妙啊,这样解决了定义 type 为不同类型的问题
// 其实是一个 if-else 的编译期选择绑定
typedef typename mpl::if_c<(is_pointer<F>::value),
function_ptr_tag,
function_obj_tag>::type ptr_or_obj_tag;
typedef typename mpl::if_c<(is_member_pointer<F>::value),
member_ptr_tag,
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
typedef typename mpl::if_c<(is_reference_wrapper<F>::value),
function_obj_ref_tag,
ptr_or_obj_or_mem_tag>::type or_ref_tag;
public:
typedef or_ref_tag type;
};
// vtable_type 大概代码如下
typedef boost::detail::function::basic_vtable0<R> vtable_type;
template<typename R >
struct basic_vtable4
{
template<typename F>
bool assign_to(F f, function_buffer& functor) {
typedef typename get_function_tag<F>::type tag;
return assign_to(f, functor, tag());
}
// 以下重载了几种 tag
// 普通指针对象
template<typename FunctionPtr>
bool assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) {
this->clear(functor);
if (f) {
// 普通函数指针都是转换成 (void (*)())(f) 指针
functor.func_ptr = (void (*)())(f);
return true;
} else {
return false;
}
}
// 仿函数对象
template<typename FunctionObj>
bool assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) {
if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
// 小对象优化
assign_functor(f, functor,
mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
return true;
} else {
return false;
}
}
// 具体的小对象优化
template<typename FunctionObj>
void assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) {
functor.obj_ptr = new FunctionObj(f);
}
template<typename FunctionObj>
void assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) {
new ((void*)&functor.data) FunctionObj(f);
}
};
|
最后调用一目了然了
1
2
3
4
5
6
|
inline function4<R , T0 , T1 , T2 , T3>::operator()( T0 a0 , T1 a1 , T2 a2 , T3 a3) const {
if (this->empty())
boost::throw_exception(bad_function_call());
return get_vtable()->invoker
(this->functor , a0 , a1 , a2 , a3);
}
|