在源代码中gcc的std :: bind将参数复制到数据结构中? [英] Where in the source does gcc's std::bind copy arguments into a data structure?

查看:303
本文介绍了在源代码中gcc的std :: bind将参数复制到数据结构中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了理解 std :: bind 分配内存的情况,我查看了这个回答,这给了一些直觉,但我想要一个更详细的了解,所以我去看看 gcc 的来源。 p>

我正在检查以下源代码用于C ++标准库的gcc实现中的 std :: bind

  / ** 
* @brief std :: bind的函数模板。
* @ingroup binder
* /
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)...)
}

给定函数F和参数A和B,将它们复制到返回的数据结构中,或者是编译器生成的?

解决方案

我们只是创建一个类型特定于这个特定的 bind()有一个函数成员(可能包装成其他类型,复制/移动适当) tuple (根据需要复制/移动)。



标准没有指定任何关于内存分配的事情,但是没有必要为 bind()






此重载会返回:

  _Bind_helper< __ is_socketlike< _Func> :: value,_Func,_BoundArgs ...> :: type 
pre>

如果 __ is_socketlike< _Func> :: value false 。在这种情况下,这种类型是:

  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 ...)>类型;

忽略模板参数的含义,我们基本上构造类型:

 模板< typename _Signature> 
struct _Bind;

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

其中包含以下成员:

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

和这些相关的构造函数:

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

模板< typename ... _Args>
explicit _Bind(_Functor&& __f,_Args& ... __args)
:_M_f(std :: move(__ f)),_M_bound_args(std :: forward< _Args& ...)
{}


In trying to understand the cirumstances under which std::bind allocates memory, I looked at this answer, which gives some intuition, but I wanted a more detailed understanding, so I went and looked at the source for gcc.

I am examining the following source code for std::bind from the gcc implementation of the C++ standard library.

  /**
   *  @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)...);
    }

Given a function F and parameters A and B, where can I find the code that copies them into the returned data structure, or is this compiler generated?

解决方案

Nowhere are we allocating memory. We're just creating an object with type specific to this particular bind() that has a function member (possibly wrapped into some other type and copied/moved as appropriate) and a tuple of the arguments (copied/moved as appropriate).

The standard does not specify anything about memory allocation, but there's no need to do such a thing for bind() so any good implementation won't.


This overload is returning 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 that case, this type is:

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 template argument meaning, we're basically constructing something of type:

template<typename _Signature>
  struct _Bind;

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

which has these members:

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

and these relevant 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)...)
{ }

这篇关于在源代码中gcc的std :: bind将参数复制到数据结构中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆