前两天有朋友问我std::bind
是如何实现的,对照STL讲述原理后朋友表示还是很难理解,这可以理解,因为STL涉及到的东西太多,很难清晰的将核心部分显式出来。为了解释清楚这个问题,我自己实现了一个bind功能。当然了,比std::bind
要简单非常非常多,缺少很多有用的特性,但是也能展示bind的核心原理了。
template<int _Nx> |
首先占位符其实就是一个空类型,我们不需要类型里有什么,只是想要一个类型标识符。
然后看到最关键的_MyBind
类模板,该类模板有数据成员_MyList
和_f
,用于存放绑定的函数和参数。在构造对象的时候数据成员会被填充,并且在调用template<typename ... CallArg> R operator()(CallArg... arg)
的时候使用这两个数据成员。这里比较难理解的是call_tuple
函数模板,该函数需要将绑定的参数列表和后续调用的参数列表传入函数,
最后使用SFINAE的技巧有选择的通过operator[]
获取对应的值。如果std::get<S>(_MyList)
返回的是绑定的具体值,那么通过template<typename T> T operator[] (T &t) { return t; }
返回值本身,注意这里的t
是最外层_MyList
中的元素;如果std::get<S>(_MyList)
返回的是占位符,那么将通过template<int N> typename std::tuple_element<N, std::tuple<Arg...>>::type operator[] (_MyPh<N>) { return std::get<N>(_MyList); }
返回c
中_MyList
的元素,请注意这里的this
对象是c
。
当然为了使用方便需要一个函数模板mybind
,它只需要指定一个返回类型就可以使用了。