std::function的大小为何是24字节?
在32位windows上面,指针的大小就是32(size_t),但是我发现std::function却是24字节。
如果function只是一个对于函数指针的包装,那么它为什么相当于6个函数指针大小? 它还存储了哪些信息呢?
即使是看源代码,VC10的<functional>里面,模板类function里面我没有发现有数据成员啊,就是一堆函数而已。它到底是怎么保存函数指针和functor的? 奇怪了,sizeof竟然还是24,如下,我摘了代码过来:
它的私有成员都在哪里呢?
我对比了一下boost,boost::function也没有看到有成员变量。boost::function<void(void)>竟然是32,比VC的实现还要大。这究竟是为什么?
VC的源代码:
template<class _Fty> class function : public _Get_function_impl<_Fty>::_Type { // wrapper for callable objects public: typedef function<_Fty> _Myt; typedef typename _Get_function_impl<_Fty>::_Type _Mybase; function() { // construct empty function wrapper this->_Reset(); } function(const _Myt& _Right) { // construct holding copy of _Right this->_Reset((const _Mybase&)_Right); } template<class _Fx> function(_Fx _Func _NOT_INTEGRAL(_Fx)) { // construct wrapper holding copy of _Func this->_Reset(_Func); } template<class _Fx, class _Alloc> function(_Fx _Func _NOT_INTEGRAL(_Fx), const _Alloc& _Ax) { // construct wrapper holding copy of _Func this->_Reset_alloc(_Func, _Ax); } template<class _Fx> function(reference_wrapper<_Fx> _Func) { // construct wrapper holding reference to_Func this->_Reset(_Func); } template<class _Fx, class _Alloc> function(reference_wrapper<_Fx> _Func, const _Alloc& _Ax) { // construct wrapper holding reference to_Func this->_Reset_alloc(_Func, _Ax); } function(_Unutterable) { // construct empty function wrapper from null pointer this->_Reset(); } #if defined(_NATIVE_NULLPTR_SUPPORTED) \ && !defined(_DO_NOT_USE_NULLPTR_IN_STL) function(int) { // construct empty function wrapper from null pointer this->_Reset(); } #endif /* defined(_NATIVE_NULLPTR_SUPPORTED) etc. */ ~function() { // destroy the object this->_Tidy(); } _Myt& operator=(const _Myt& _Right) { // assign _Right if (this != &_Right) { // clean up and copy this->_Tidy(); this->_Reset((const _Mybase&)_Right); } return (*this); } function(_Myt&& _Right) { // construct holding moved copy of _Right this->_Resetm((_Mybase&)_Right); } _Myt& operator=(_Myt&& _Right) { // assign by moving _Right if (this != &_Right) { // clean up and copy this->_Tidy(); this->_Resetm((_Mybase&)_Right); } return (*this); } template<class _Fx> _Myt& operator=(_Fx _Func _NOT_INTEGRAL(_Fx)) { // assign function object _Func this->_Tidy(); this->_Reset(_Func); return (*this); } function& operator=(_Unutterable) { // clear function object this->_Tidy(); this->_Reset(); return (*this); } #if defined(_NATIVE_NULLPTR_SUPPORTED) \ && !defined(_DO_NOT_USE_NULLPTR_IN_STL) function& operator=(int) { // clear function object this->_Tidy(); this->_Reset(); return (*this); } #endif /* defined(_NATIVE_NULLPTR_SUPPORTED) etc. */ template<class _Fx> _Myt& operator=(reference_wrapper<_Fx> _Func) { // assign wrapper holding reference to_Func this->_Tidy(); this->_Reset(_Func); return (*this); } template<class _Fx, class _Alloc> void assign(_Fx _Func _NOT_INTEGRAL(_Fx), const _Alloc& _Ax) { // construct wrapper holding copy of _Func this->_Tidy(); this->_Reset_alloc(_Func, _Ax); } template<class _Fx, class _Alloc> void assign(reference_wrapper<_Fx> _Func, const _Alloc& _Ax) { // construct wrapper holding reference to_Func this->_Tidy(); this->_Reset_alloc(_Func, _Ax); } void swap(_Myt& _Right) { // swap with _Right this->_Swap(_Right); } _OPERATOR_BOOL() const { // test if wrapper holds null function pointer return (!this->_Empty() ? _CONVERTIBLE_TO_TRUE : 0); } const _XSTD2 type_info& target_type() const { // return type_info object for target type return (this->_Target_type()); } template<class _Fty2> _Fty2 *target() { // return pointer to target object return ((_Fty2*)this->_Target(typeid(_Fty2))); } template<class _Fty2> const _Fty2 *target() const { // return pointer to target object return ((const _Fty2*)this->_Target(typeid(_Fty2))); } private: template<class _Fty2> void operator==(const function<_Fty2>&); // not defined template<class _Fty2> void operator!=(const function<_Fty2>&); // not defined };
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>class function<BOOST_FUNCTION_PARTIAL_SPEC> : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>{ typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type; typedef function self_type; struct clear_type {};public: function() : base_type() {} template<typename Functor> function(Functor f#ifndef BOOST_NO_SFINAE ,typename enable_if_c< (boost::type_traits::ice_not< (is_integral<Functor>::value)>::value), int>::type = 0#endif ) : base_type(f) { } template<typename Functor,typename Allocator> function(Functor f, Allocator a#ifndef BOOST_NO_SFINAE ,typename enable_if_c< (boost::type_traits::ice_not< (is_integral<Functor>::value)>::value), int>::type = 0#endif ) : base_type(f,a) { }#ifndef BOOST_NO_SFINAE function(clear_type*) : base_type() {}#endif 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>#ifndef BOOST_NO_SFINAE typename enable_if_c< (boost::type_traits::ice_not< (is_integral<Functor>::value)>::value), self_type&>::type#else self_type&#endif operator=(Functor f) { self_type(f).swap(*this); return *this; }#ifndef BOOST_NO_SFINAE self_type& operator=(clear_type*) { this->clear(); return *this; }#endif self_type& operator=(const base_type& f) { self_type(f).swap(*this); return *this; }};