Nowhere do we allocate memory. We just create an object with a type specific to that particular bind() that has a member of the function (possibly wrapped in some other type and copied / moved as needed) and tuple arguments (copied / moved as needed).
The standard does not say anything about memory allocation, but there is no need to do such a thing for bind() , so any good implementation will not.
This overload returns a:
_Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
This overload only participates in overload resolution if __is_socketlike<_Func>::value is false . In this case, this type:
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;
Ignoring the value of the template argument, we basically build something like:
template<typename _Signature> struct _Bind; template<typename _Functor, typename... _Bound_args> class _Bind<_Functor(_Bound_args...)> : public _Weak_result_type<_Functor> { ... };
which has the following elements:
_Functor _M_f; tuple<_Bound_args...> _M_bound_args;
and related constructors:
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)...) { }
Barry source share