std :: function <void(int&)> type的大小</void(int&)>

时间:2012-11-21 23:06:45

标签: c++ gcc stl c++11

来自C ++ 11的std::function<void(int&)>sizeof = 32的神奇之处是什么?如果我将函数引用存储为指针,则只需8 bytes(在64位计算机上)。

2 个答案:

答案 0 :(得分:15)

对于std::function<Signature>,它是对象大小和分配之间的权衡,这是有趣的:对于小函数对象,希望避免分配。另一方面,这样做会增加对象的大小。为了使小函数优化变得有用并且在实际调用对象时不引入开销,对象大小需要至少两个指针加上一些内存来存储简单的函数对象。似乎32字节的大小就是这样(在sizeof(T*)为8的系统上)。

也就是说,std::function<Signature>对象内部存储一个继承层次结构:基类提供要调用的接口,委托给实现调用接口的模板化派生(加上,可能还有一些clone()功能)。在针对大小优化的实现中,函数对象只保留指向基类的指针,但是为了避免分配,它会留出一些内部存储来分配整个对象并指向该对象(内部指针在实际调用时避免了一个条件)功能对象)。对象所需的内存是虚函数指针加上std::function<Signature>对象初始化的实际函数对象的任何数据。为了容纳成员函数及其对象,似乎还有两个单词相当小。

答案 1 :(得分:8)

std::function确实很神奇,因为它可以从任何可调用对象构建!它会愉快地存储任何数量的状态,即使表面上你保留了一个微不足道的void(int&)签名。

这种魔法肯定会附加价格,它通常在内部使用某种类型的擦除(即动态分配和虚拟调度)。细节有所不同,但由此产生的对象肯定是重的&#34; - 这就是为什么在可行的情况下应该避免使用auto和模板的原因!