我分析的是gcc的function源码。
首先看函数指针怎么存储
class _Undefined_class;//永远不会实现的class
union _Nocopy_types{
void* _M_object;//function object指针
const void* _M_const_object;//const function object指针
void(*_M_function_pointer)();//函数指针
void (_Undefined_class::*_M_member_pointer)();//成员函数指针
};
union _Any_data{
void* _M_access() { return &_M_pod_data[0]; }
const void* _M_access() const { return &_M_pod_data[0]; }
template<typename _Tp>
_Tp& _M_access(){
return *static_cast<_Tp*>(_M_access());
}
template<typename _Tp>
const _Tp& _M_access() const{
return *static_cast<const _Tp*>(_M_access());
}
_Nocopy_types _M_unused;
char _M_pod_data[sizeof(_Nocopy_types)];
};
和boost的实现手法有些近似,有意思的是union有点像类,A union can have member functions (including constructors and destructors), but not virtual (10.3) functions。_Any_data的大小在x86下应该是4个字节。
接着是function_base,从类型定义中可以看出是为了存储指针
enum _Manager_operation
{
__get_type_info,
__get_functor_ptr,
__clone_functor,
__destroy_functor
};
/// Base class of all polymorphic function object wrappers.
class _Function_base
{
public:
static const std::size_t _M_max_size = sizeof(_Nocopy_types);
static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
...
_Function_base() : _M_manager(nullptr) { }
~_Function_base()
{
if (_M_manager)
_M_manager(_M_functor, _M_functor, __destroy_functor);
}
bool _M_empty() const { return !_M_manager; }
typedef bool(*_Manager_type)(_Any_data&, const _Any_data&,
_Manager_operation);
_Any_data _M_functor;//function buffer
_Manager_type _M_manager;//manager
};
下来我们看manager,和boost的实现机制一样,该类型在_Function_base中定义,优点是把东西都放一起了。而不在另外一个命名空间,比boost多了个empty的判断
template<typename _Functor>
class _Base_manager
{
protected:
static const bool __stored_locally =
(__is_location_invariant<_Functor>::value
&& sizeof(_Functor) <= _M_max_size
&& __alignof__(_Functor) <= _M_max_align
&& (_M_max_align % __alignof__(_Functor) == 0));
typedef integral_constant<bool, __stored_locally> _Local_storage;
// Retrieve a pointer to the function object
static _Functor* _M_get_pointer(const _Any_data& __source)
{
const _Functor* __ptr =
__stored_locally ? std::__addressof(__source._M_access<_Functor>())
/* have stored a pointer */ : __source._M_access<_Functor*>();
return const_cast<_Functor*>(__ptr);
}
// Clone a location-invariant function object that fits within
// an _Any_data structure.
static void _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
{
new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
}
// Clone a function object that is not location-invariant or
// that cannot fit into an _Any_data structure.
static void _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
{
__dest._M_access<_Functor*>() = new _Functor(*__source._M_access<_Functor*>());
}
// Destroying a location-invariant object may still require
// destruction.
static void _M_destroy(_Any_data& __victim, true_type)
{
__victim._M_access<_Functor>().~_Functor();
}
// Destroying an object located on the heap.
static void _M_destroy(_Any_data& __victim, false_type)
{
delete __victim._M_access<_Functor*>();
}
public:
// Manager具体实现
static bool _M_manager(_Any_data& __dest, const _Any_data& __source,
_Manager_operation __op)
{
switch (__op)
{
case __get_type_info:
__dest._M_access<const type_info*>() = &typeid(_Functor);
break;
case __get_functor_ptr:
__dest._M_access<_Functor*>() = _M_get_pointer(__source);
break;
case __clone_functor:
_M_clone(__dest, __source, _Local_storage());
break;
case __destroy_functor:
_M_destroy(__dest, _Local_storage());
break;
}
return false;
}
static void _M_init_functor(_Any_data& __functor, _Functor&& __f)
{
_M_init_functor(__functor, std::move(__f), _Local_storage());
}
template<typename _Signature>
static bool _M_not_empty_function(const function<_Signature>& __f)
{
return static_cast<bool>(__f);
}
template<typename _Tp>
static bool _M_not_empty_function(_Tp* const& __fp)
{
return __fp;
}
template<typename _Class, typename _Tp>
static bool _M_not_empty_function(_Tp _Class::* const& __mp)
{
return __mp;
}
template<typename _Tp>
static bool _M_not_empty_function(const _Tp&)
{
return true;
}
private:
static void _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
{
new (__functor._M_access()) _Functor(std::move(__f));
}
static void _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
{
__functor._M_access<_Functor*>() = new _Functor(std::move(__f));
}
};
先说下_Maybe_unary_or_binary_function,这个主要是为了兼容原来标准中的unay_function,binary_function,
/**
* Derives from @c unary_function or @c binary_function, or perhaps
* nothing, depending on the number of arguments provided. The
* primary template is the basis case, which derives nothing.
*/
template<typename _Res, typename... _ArgTypes>
struct _Maybe_unary_or_binary_function { };
/// Derives from @c unary_function, as appropriate.
template<typename _Res, typename _T1>
struct _Maybe_unary_or_binary_function<_Res, _T1>
: std::unary_function<_T1, _Res> { };
/// Derives from @c binary_function, as appropriate.
template<typename _Res, typename _T1, typename _T2>
struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
: std::binary_function<_T1, _T2, _Res> { };
接着是function的本身
template<typename _Cond, typename _Tp>
using _Requires = typename enable_if<_Cond::value, _Tp>::type;
template<typename _Res, typename... _ArgTypes>
class function<_Res(_ArgTypes...)>
: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
private _Function_base
{
typedef _Res _Signature_type(_ArgTypes...);
template<typename _Func,
typename _Res2 = typename result_of<_Func(_ArgTypes...)>::type>
struct _Callable : __check_func_return_type<_Res2, _Res> { };
// Used so the return type convertibility checks aren't done when
// performing overload resolution for copy construction/assignment.
template<typename _Tp>
struct _Callable<function, _Tp> : false_type { };
template<typename _Cond, typename _Tp>
using _Requires = typename enable_if<_Cond::value, _Tp>::type;
public:
typedef _Res result_type;
_Res operator()(_ArgTypes... __args) const
{
if (_M_empty())
__throw_bad_function_call();
return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
}
bool _M_empty() const {
return !_M_manager;
}
//c++11的safe bool惯用法
explicit operator bool() const noexcept
{
return !_M_empty();
}
template<typename _Functor,
typename = _Requires<__not_<is_same<_Functor, function>>, void>,
typename = _Requires<_Callable<_Functor>, void>>
function(_Functor);
private:
using _Invoker_type = _Res(*)(const _Any_data&, _ArgTypes&&...);
_Invoker_type _M_invoker;
};
然后是这个invoke_type了,这个类型比较多,不一一展开,只选一个
template<typename _Signature, typename _Functor>
class _Function_handler;
template<typename _Res, typename _Functor, typename... _ArgTypes>
class _Function_handler<_Res(_ArgTypes...), _Functor>
: public _Function_base::_Base_manager<_Functor>
{
typedef _Function_base::_Base_manager<_Functor> _Base;
public:
static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
{
return (*_Base::_M_get_pointer(__functor))(
std::forward<_ArgTypes>(__args)...);
}
};
再就是给invoke和mannage赋值了
template<typename _Res, typename... _ArgTypes>
template<typename _Functor, typename, typename>
function<_Res(_ArgTypes...)>::
function(_Functor __f)
: _Function_base()
{
typedef _Function_handler<_Signature_type, _Functor> _My_handler;
if (_My_handler::_M_not_empty_function(__f))
{
_My_handler::_M_init_functor(_M_functor, std::move(__f));
_M_invoker = &_My_handler::_M_invoke;
_M_manager = &_My_handler::_M_manager;
}
}
值得注意的就是Variadic Template的语法了