前两天有朋友问我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,它只需要指定一个返回类型就可以使用了。