2016-04-14 12 views
6

std::bind'un bellek ayırdığı durumları anlamaya çalışırken, bazı sezgiler veren this answer'a baktım, ama daha ayrıntılı bir anlayış istedim, bu yüzden gidip gcc kaynağına baktım.Kaynakta, gcc'nin std :: copy argümanlarını bir veri yapısına bağlar mı?

C++ standart kitaplığının gcc uygulamasından std::bind için following source code incelemeyi yapıyorum. F ve parametreler A ve B bir fonksiyon Verilen

/** 
    * @brief Function template for std::bind. 
    * @ingroup binders 
    */ 
    template<typename _Func, typename... _BoundArgs> 
    inline typename 
    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type 
    bind(_Func&& __f, _BoundArgs&&... __args) 
    { 
     typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type; 
     typedef typename __helper_type::__maybe_type __maybe_type; 
     typedef typename __helper_type::type __result_type; 
     return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), 
       std::forward<_BoundArgs>(__args)...); 
    } 

, nerede döndürülen veri yapısı içine kodunu kopyalar bunları bulabilirsiniz, ya da bu derleyici oluşturulur?

+0

Bin d yığından herhangi bir bellek ayırmaya gerek yoktur. –

+0

Bu, bağlantılı cevabın yanlış olduğu anlamına mı geliyor? Ayrıca yığın veya parametreler hala kopyalanmalıdır. – merlin2011

+1

Bana uygun görünüyor.std :: function yığında bir şeyler ayırır (std :: bind dönüş değeri). std :: bind gerek yok. Bağımsız değişkenlerin kopyalandığı nihai yer, "Bind_" sınıfının bir 'tuple _M_bound_args' üyesidir. –

cevap

1

Bu hat:

__result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), std::forward<_BoundArgs>(__args)...); 

parametreler, her iki çağrılabilir (__do_wrap ile sarılmış) ve bağımsız değişkenler, bir veri yapısı içinde onları muhtemel saklar __result_type tip iletilir.

__result_type kodunu aramanız gerekir; bu, yukarıda belirtilen iki satırda (yani, _Bind_helper<false, _Func, _BoundArgs...>::type) uygulama tanımlı türde eski tarafından döndürülen verileri sarar.
Gerçek tür, hem callable hem de argümanları kabul eden bir kurucuya sahip olan _Bind (arama class _Bind) ve tabii ki bir şablon sınıfıdır (çevresinde birkaç yardımcı tarafından açıklanmıştır).
Aslında, Bind_helper<whatever>::type (döndürülen tür) typedef _Bind<whatever> type olarak tanımlanmıştır, bu sınıfı arayabilir ve hepsi budur.

+0

Zaten bir tane olan ['__do_wrap'] (https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/functional#L875) 'e baktım. örtülü olarak yapmazsa, bellek ayırma görünmeyen liner. Sonuç türü, şablonlardan oluşturulan türden bir tür gibi görünüyor. – merlin2011

+0

Üzgünüm, ihmal edelim __do_wrap', benim hatam. Anahtar "__result_type" gibi görünüyor. – skypjack

+0

Doğru anlıyorsam, atıfta bulunduğunuz son sınıf, kaynak formunda mevcut olmayabilir mi? – merlin2011

1

Hiçbir yer bellek ayırmıyoruz. Bu özel bind()'a özgü tipte bir nesne oluşturuyoruz (bu, muhtemelen başka bir türe sarılmış ve uygun şekilde kopyalanmış/taşınmış) ve argümanların bir tuple (uygun şekilde kopyalandı/taşındı).

Standart bellek ayırma ile ilgili hiçbir şey belirtmez, ancak bind() için böyle bir şey yapmaya gerek yoktur, böylece iyi bir uygulama yapılmayacaktır.


Bu aşırı yük

bir döndürüyor: __is_socketlike<_Func>::value false ise

_Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type 

Bu aşırı yük yalnızca aşırı yük çözünürlükte katılır. Bu durumda, bu tür:

template<typename _Signature> 
    struct _Bind; 

template<typename _Functor, typename... _Bound_args> 
class _Bind<_Functor(_Bound_args...)> 
: public _Weak_result_type<_Functor> 
{ 
    ... 
}; 

bu üyesi vardır:

_Functor _M_f; 
tuple<_Bound_args...> _M_bound_args; 

ve

typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> __maybe_type; 
typedef typename __maybe_type::type __func_type; 
typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; 

, temelde tip bir şey inşa ediyoruz şablon argümanı anlamını göz ardı edilmesi ilgili ilgili kurucular:

template<typename... _Args> 
explicit _Bind(const _Functor& __f, _Args&&... __args) 
: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) 
{ } 

    template<typename... _Args> 
explicit _Bind(_Functor&& __f, _Args&&... __args) 
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) 
{ } 
İlgili konular