互聯網上的一些資源(特別是this one)表示std :: function使用小封閉優化,例如,如果封閉件大小比數據的一定量的下它不分配堆(以上鍊接指示16個字節用於GCC)g ++:使用閉包類型初始化的std :: function始終使用堆分配?
所以我去到g挖++頭
看起來像是否被施加這樣的優化決定通過在 「功能」 標題(克++ 4.6.3)
static void
_M_init_functor(_Any_data& __functor, _Functor&& __f)
{ _M_init_functor(__functor, std::move(__f), _Local_storage()); }
的代碼塊和一些線向下:
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)); }
};
例如如果_Local_storage()是true_type,比投放新的叫,否則 - _Local_storage的常新
確定指標是如下因素:
typedef integral_constant<bool, __stored_locally> _Local_storage;
和__stored_locally:
static const std::size_t _M_max_size = sizeof(_Nocopy_types);
static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
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));
最後:__is_location_invariant:
template<typename _Tp>
struct __is_location_invariant
: integral_constant<bool, (is_pointer<_Tp>::value
|| is_member_pointer<_Tp>::value)>
{ };
所以。就我所知,閉包類型既不是指針也不是成員指針。爲了驗證我甚至寫了一個小測試程序:
#include <functional>
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "max stored locally size: " << sizeof(std::_Nocopy_types) << ", align: " << __alignof__(std::_Nocopy_types) << std::endl;
auto lambda = [](){};
typedef decltype(lambda) lambda_t;
std::cout << "lambda size: " << sizeof(lambda_t) << std::endl;
std::cout << "lambda align: " << __alignof__(lambda_t) << std::endl;
std::cout << "stored locally: " << ((std::__is_location_invariant<lambda_t>::value
&& sizeof(lambda_t) <= std::_Function_base::_M_max_size
&& __alignof__(lambda_t) <= std::_Function_base::_M_max_align
&& (std::_Function_base::_M_max_align % __alignof__(lambda_t) == 0)) ? "true" : "false") << std::endl;
}
,輸出是:
max stored locally size: 16, align: 8
lambda size: 1
lambda align: 1
stored locally: false
所以,我的問題是:是intializing的std ::與lambda函數總是堆結果分配?或者我錯過了什麼?
我這個程序確認你的發現:http://ideone.com/kzae6U您可以檢查鐺(HTTP:// melpon.org/wandbox/),相同的程序只爲內存分配非常大的捕獲... – PiotrNycz