gcc 的 std::bind 在源中的哪个位置将参数复制到数据结构中?



在试图理解std::bind分配内存的条件时,我看了这个答案,它给出了一些直觉,但我想要更详细的理解,所以我去看了gcc的来源。

我正在研究以下来自C++标准库的gcc实现的std::bind的源代码。

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

给定一个函数F和参数a和B,我在哪里可以找到将它们复制到返回的数据结构中的代码,或者这个编译器是生成的?

此行:

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

参数,包括可调用的(用__do_wrap包装)和自变量,都被转发到__result_type类型,该类型可能将它们存储在数据结构中。

您应该查找代码__result_type,它将前者返回的数据封装在上面两行提到的实现定义类型中(即_Bind_helper<false, _Func, _BoundArgs...>::type
实际类型是_Bind(搜索class _Bind),它有一个接受可调用和参数的构造函数,当然,它是一个模板类(通过一些助手公开)
事实上,Bind_helper<whatever>::type(即返回的类型)被定义为typedef _Bind<whatever> type,您可以查找该类,仅此而已。

我们没有在任何地方分配内存。我们只是创建一个类型特定于该特定bind()的对象,该对象具有一个函数成员(可能封装到其他类型中,并根据情况进行复制/移动)和一个参数的tuple(根据情况进行拷贝/移动)。

该标准没有指定任何关于内存分配的内容,但没有必要为bind()做这样的事情,所以任何好的实现都不会。


此过载返回一个:

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

如果__is_socketlike<_Func>::valuefalse,则该过载仅参与过载解决。在这种情况下,这种类型是:

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;

忽略模板参数的含义,我们基本上是在构建某种类型的东西:

template<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)...)
{ }
  template<typename... _Args>
explicit _Bind(_Functor&& __f, _Args&&... __args)
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
{ }

最新更新