• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C++ STL 内 std::{bind/tuple/function} 简单实现

c++ 搞代码 4年前 (2022-01-06) 23次浏览 已收录 0个评论

这篇文章主要介绍了C++ STL 内 std::{bind/tuple/function} 简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

基本逻辑思考

首先是实现 function,这个比较简单,重载 operator() 就好,这里只实现对函数指针的包装

其次是实现 tuple,这个会比较绕,通过模板取第一个参数,然后用剩下的参数继续生成  tuple并继承,是一种递归的思想

有了 tuple 就要有 get(),这个就更比较绕了,首先是需要类似的方式实现获得 tuple 的值类型与元组类型,然后通过强制来源gaodaimacom搞#代%码网类型转换,获取对应的层级的 value

接下来是 bind,首先要解决的就是如何保存创建时的参数列表,这里就用到 tuple 来保存了

奇技淫巧还是运行函数时取相应的元组的对应位置的值,还是类似的方式,通过特化模板,公式是  => ,比如 3 最后会生成 0 0 1 2 那么抛弃第一个,并用来展开元组,传递给函数指针

最重要的来了,就是如何实现 placeholders,简单来说就是在上一步的 operator() 增加传入参数,并制造成元组 r_args,然后带进一个 _unwrap_tuple 类,这里会重载 operator[] 根据传入数据结构,如果是 _placeholders 那么取 r_args 相应的 index 位置,否则会直接  return

代码

不多说,还是直接放代码,仅作为参考,有写的不好的地方轻喷

 /* * Author: SpringHack - [email protected] * Last modified: 2020-02-19 10:16:17 * Filename: main.cpp * Description: Created by SpringHack using vim automatically. */ #include  namespace dosk { // begin namespace dosk // function template  class function; template  class function { private: Result (*function_)(Args...); public: typedef Result return_type; function() = default; function(Result (*fn)(Args...)) : function_(fn) {}; Result operator()(Args... a) { return function_(a...); } function& operator=(Result (*fn)(Args...)) { function_ = fn; return *this; } }; // tuple template  class tuple; template  class tuple : public tuple { public: HEAD value; tuple(HEAD head, LIST... list) : tuple(list...), value(head) {}; }; template  class tuple {}; // tuple get template  class _tuple_type; template  class _tuple_type<index, tuple> { public: typedef typename _tuple_type<index - 1, tuple>::value_type value_type; typedef typename _tuple_type<index - 1, tuple>::tuple_type tuple_type; }; template  class _tuple_type<0, tuple> { public: typedef HEAD value_type; typedef tuple tuple_type; }; template  typename _tuple_type<index, tuple>::value_type get(tuple t) { typedef typename _tuple_type<index, tuple>::value_type value_type; typedef typename _tuple_type<index, tuple>::tuple_type tuple_type; value_type rv = ((tuple_type)t).value; return rv; } // bind template  class _tuple_index {}; template  class _make_indexs : public _make_indexs {}; template class _make_indexs { public: typedef _tuple_index index_type; }; namespace placeholders { template  class _placeholders {}; _placeholders _1; _placeholders _2; _placeholders _3; _placeholders _4; _placeholders _5; _placeholders _6; _placeholders _7; _placeholders _8; _placeholders _9; _placeholders _10; template  class _unwrap_tuple { public: tuple r_args; _unwrap_tuple(tuple r_args) : r_args(r_args) {}; template  R operator[](R r) { return r; } template  auto operator[](placeholders::_placeholders) { return get(r_args); } }; }; template  class bind_t { public: typedef typename _make_indexs::index_type _indexs; typedef typename Func::return_type return_type; Func func; tuple args; bind_t(Func func, Args... args): func(func), args(args...) {} template  return_type operator()(RArgs&&... _r_args) { tuple r_args = tuple(_r_args...); return run(_indexs(), r_args); } template  return_type run(_tuple_index, tuple r_args) { return func(unwrap_args(r_args)...); } template  auto unwrap_args(tuple r_args) { placeholders::_unwrap_tuple _u_a(r_args); auto _m_a = get(args); return _u_a[_m_a]; } }; template  bind_t bind(Func& func, Args&&... args) { return bind_t(func, args...); } }; // end namespace dosk // Test code std::string test_func(int a, const char * b) { return std::to_string(a) + std::string(b); } std::string test_bind_args(int a, int b, int c, int d, int e) { return std::to_string(a) + std::to_string(b) + std::to_string(c) + std::to_string(d) + std::to_string(e); } int main() { // Test tuple dosk::tuple t(123, "456"); std::cout << dosk::get(t) << dosk::get(t) << std::endl; // Test function dosk::function closure_1 = test_func; std::cout << closure_1(123, "456") << std::endl; // Test bind dosk::function closure_2 = test_bind_args; auto binder = dosk::bind(closure_2, 1, dosk::placeholders::_2, 3, dosk::placeholders::_1, 5); std::cout << binder(4, 2, 0) << std::endl; return 0; } 

以上就是C++ STL 内 std::{bind/tuple/function} 简单实现的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C++ STL 内 std::{bind/tuple/function} 简单实现

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址