std::function的大小为何是24字节?

zwerww zwerww 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
在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
};


boost的实现是在function_template.hpp文件里,源代码如下:

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;
}
};
...全文

相关推荐

C++11中lambda、std::function和std:bind详解

大家都知道C++11中增加了许多的新特性,下面在这篇文中我们就来聊一下lambda表达式,闭包,std::function以及std::bind。文中介绍的很详细,相信对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。

weixin_38522529

C++ 11 std::function和std::bind使用详解

主要介绍了C++ 11 std::function和std::bind使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

weixin_38689477

通过c++11的std::bind及std::function实现类方法回调,模拟Qt实现信号槽

c++11引入了std::bind及std::function,实现了函数的存储和绑定,即先将可调用的对象保存起来,在需要的时候再调用。定义了SignalObject信号类和SlotObject槽类,其中信号类中的 std::function _call就是要绑定的槽函数,即回调函数

但行技术

理解C++编程中的std::function函数封装

先来看看下面这两行代码: std::function<void> onKeyPressed; std::function<void> onKeyReleased; 这两行代码是从Cocos2d-x中摘出来的,重点是这两行代码的定义啊。std::function这是什么东西?如果你对上述两行代码表示毫无压力,那就不妨再看看本文,就当温故而知新吧。 std::function介绍 类模版std::function是一种通用、多态的函数封装。std::function的

weixin_38571992

C++11 std::function:函数类型擦除与一等公民抽象

在C++中,函数抽象长期受限于编译期绑定与签名刚性。std::function通过类型擦除技术,将可调用对象(函数指针、lambda、成员函数、bind表达式)统一为运行时可携带状态、可组合替换的一等公民。其底层基于模板实例化与内存布局控制,实现零开销抽象,兼顾静态安全与工程灵活性。结合可变参数模板和lambda,std::function支撑泛型事件总线、异步任务调度等现代C++架构模式;而小对象优化(SOO)机制则直接影响高频回调场景的性能表现。作为C++11函数式编程基石,它标志着从语法糖到系统级抽象

weixin_30247307
评论 4
收藏 已收藏
分享
返回顶部
zwerww
C++ 语言 65,214 成员 250,514 内容