文档章节

Effective C++: std::bind特性/std::bind实现.

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/05/08 12:41
字数 716
阅读 54
收藏 0

1, 小特性

demo1:

#include <iostream>
#include <functional>

void function(int& number)
{
	number = 50;
}

using functionType = void(*)(int&);

int main()
{
	//case 1:
	int n1 = 10;
	auto f1 = std::bind(function, 10);
	f1();
	std::cout<<n1<<std::endl; //输出: 10.
	
	//case 2:
	int n2 = 20;
	auto f2 = std::bind(function, std::ref(n2));
	f2();
	std::cout<<n2<<std::endl; //输出: 50. 
	
	//case 3:
	int n3 = 30;
	auto f3 = std::bind(function, n3);
	f3();
	std::cout<< n3 <<std::endl; //输出: 30 
	
	
	return 0;
}

 

 

2, std::bind的实现(debian GCC6.3)

 由于标准没用要求std::bind的具体实现只是要求了std::bind的具体功能.我这里只有linux. vs就不考虑了.下面让我们一点一点往下看.

 

code block 1: std::bind

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

  1), 首先我们看到 std::bind(__Func&& f,  _BoundArgs&&... __args).

 2), 虽然f的类型为: __Func&&但是仍然是可以传递一个指向class/struct member function/data的指针.

3), 我们看到std::bind依赖 _Bind_helper(struct)以及 __is_socketlike(struct).

 

code block 2:  __is_socketlike

  template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type>
    using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>;

1) __is_socketlike依赖 __or_(struct), 同时接受一个2个template argument:

                _Tp 和  _Tp2, 但是__or_(struct)并不依赖_Tp, 而是是需要获取 std::decay<_Tp>::type得到的_Tp2.

 

code block 3: __or_   和  conditional

  template<typename...>
    struct __or_; //struct template declare


  template<>
    struct __or_<>
    : public false_type
    { };   //specialized


  template<typename _B1>
    struct __or_<_B1>
    : public _B1
    { };  //specialized

  template<typename _B1, typename _B2>
    struct __or_<_B1, _B2>
    : public conditional<_B1::value, _B1, _B2>::type
    { }; //specialized

  template<typename _B1, typename _B2, typename _B3, typename... _Bn>
    struct __or_<_B1, _B2, _B3, _Bn...>
    : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
    { }; //specialized




  template<bool _Cond, typename _Iftrue, typename _Iffalse>
    struct conditional
    { typedef _Iftrue type; }; // struct template declare
 

  template<typename _Iftrue, typename _Iffalse>
    struct conditional<false, _Iftrue, _Iffalse>
   { typedef _Iffalse type; }; // specialized

 1),  首先看  conditional(struct):

       1, 当 _Cond为true的时候, conditional的类型为 _Iftrue

      2, 当_Cond为false的时候, conditional的类型为 _Iffalse

2), __or_(struct)可以接受 可变的template arguments, 但是需要注意的是我们提供的 template arguments必须是可以 operator bool 且必须具有一个 member data  value 且value必须是bool类型.

 

 

code block 4:  _Bind_helper

  template<bool _SocketLike, typename _Func, typename... _BoundArgs>
    struct _Bind_helper
    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
    {
      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;
    }; //struct template declare



  template<typename _Func, typename... _BoundArgs>
    struct _Bind_helper<true, _Func, _BoundArgs...>
    { }; //specialized

1),如果 _Sokectlike的值为true, 就表明 _Func的类型为 integer/enum, 这个时候是不能作为函数调用的因此错误.

2),  _Bind_helper依赖 _Bind_check_arity(struct), _Maybe_wrap_member_pointer(struct) 以及 _Bind(struct).

 

code block 5: _Bind_check_arity

  template<typename _Func, typename... _BoundArgs>
    struct _Bind_check_arity { };

  template<typename _Ret, typename... _Args, typename... _BoundArgs>
    struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...>
    {
      static_assert(sizeof...(_BoundArgs) == sizeof...(_Args),
                   "Wrong number of arguments for function");
    };

  template<typename _Ret, typename... _Args, typename... _BoundArgs>
    struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...>
    {
      static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args),
                   "Wrong number of arguments for function");
    };

  template<typename _Tp, typename _Class, typename... _BoundArgs>
    struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...>
    {
      using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity;
      using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs;
      static_assert(_Varargs::value
		    ? sizeof...(_BoundArgs) >= _Arity::value + 1
		    : sizeof...(_BoundArgs) == _Arity::value + 1,
		    "Wrong number of arguments for pointer-to-member");
    };

 

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 13
博文 164
码字总数 138212
作品 0
武汉
程序员
私信 提问
[C/C++]完整揭秘VS2010关于function和bind的实现

很久之前我就对C++里面的function非常感兴趣,也探究出了一些成果。 [C/C++]std::tr1::function源码剖析(一) [C/C++]std::tr1::function源码剖析(二) 这两篇文章是对VS2010中如何实现fun...

梁欢
2013/10/25
0
0
CC_CALLBACK原理及应用

c++ 11 基础 : std::function 类模版 std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标进行存储、复制、和调用操作,这些目标包括函数、lambda表达式...

霄霄月月
2014/04/07
0
1
c++11实现异步定时器

c++11提供了丰富的时间和线程操作函数,比如 std::this_thread::sleep, std::chrono::seconds等。可以利用这些来很方便的实现一个定时器。 实现 ifndef TIMERH define TIMERH include includ...

moki_oschina
2018/05/23
0
0
C++ 模板惯用法

原文:C++ 模板惯用法 作者:Breaker 关于 C++ 模板编程的惯用法,note-to-self + keynote + idiom case + cross-reference 式笔记 目录 模板语法 模板惯用法示例 堆栈上分配 编译优化的开关...

晨曦之光
2012/05/23
1K
0
c++ java中关于protobuf反序列化对象实体和实体处理(函数)关系(二)

上一篇中大概描述了c++ java中关于protobuf反序列化对象实体和实体处理(函数)关系,并贴出了java的实现方案,针对c++版本也只是简单的描述了一下 采用std::bind().这里采用 id+ 指针,通过I...

石头哥哥
2015/02/08
0
3

没有更多内容

加载失败,请刷新页面

加载更多

Navicat怎样导入Excel表格和txt文本的数据

Navicat怎样导入Excel表格和txt文本的数据 2018年07月02日 11:29:11 零碎de記憶 阅读数:2433 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39135287/ar...

linjin200
11分钟前
0
0
使用MaxCompute Java SDK运行安全相关命令

使用MaxCompute Console的同学,可能都使用过MaxCompute安全相关的命令。官方文档上有详细的MaxCompute 安全指南 ,并给出了安全相关语句汇总 。 简而言之, 权限管理 、 列级别访问控制 、 ...

阿里云云栖社区
16分钟前
0
0
中小公司的Java工程师应该如何逆袭冲进BAT?

(1)80% Java工程师都有的迷茫 这篇文章,跟大家聊一聊很多很多很多人问我的一个问题:中小公司的Java工程师应该如何规划准备,才能跳槽进入BAT这类一线互联网公司? 之所以我用了三个 “很...

Java填坑路
17分钟前
1
0
你的应用够安全吗?绿标2.0隐私权限详解

近日,最新一期的《绿色应用达标率调查报告》结果显示,应用在安全方面的通过率仅为57%,相较于其他四项标准通过率最低。其中隐私权限的过度获取是主要原因之一,需要开发者尽快完成整改。 ...

安卓绿色联盟
27分钟前
0
0
使用MaxCompute Java SDK运行安全相关命令

使用MaxCompute Console的同学,可能都使用过MaxCompute安全相关的命令。官方文档上有详细的MaxCompute安全指南,并给出了安全相关语句汇总。 简而言之,权限管理、列级别访问控制、项目空间...

阿里云官方博客
32分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部