function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起。

这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用

基本运算符 和 基本比较符号组件

	template<class Arg, class Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
}; template<class Arg1, class Arg2, class Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
}; template<class T>
struct plus : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const
{
return x + y;
}
}; template<class T>
struct minus :binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const
{
return x - y;
}
}; template<class T>
struct multiplies : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const
{
return x*y;
}
}; template <class T>
struct modulus : binary_function <T, T, T>
{
T operator() (const T& x, const T& y) const
{
return x%y;
}
}; template<class T>
struct negate :unary_function<T, T>
{
T operator()(const T& x) const
{
return -x;
}
}; template<class T>
struct less :binary_function<T, T, bool>
{
bool operator()(const T&lhs, const T& rhs) const
{
return lhs < rhs;
}
}; template <class T>
struct greater : binary_function<T, T, bool>
{
bool operator()(const T& lhs, const T& rhs) const
{
return lhs > rhs;
}
}; template <class T>
struct equal_to : binary_function <T, T, bool>
{
bool operator() (const T& x, const T& y) const
{
return x == y;
}
}; template<class T>
struct greater_equal : binary_function<T, T, bool>
{
bool operator()(const T& lhs, const T& rhs)
{
return lhs >= rhs;
}
}; template<class T>
struct less_equal : binary_function<T, T, bool>
{
bool operator()(const T& lhs, const T& rhs)
{
return lhs <= rhs;
}
};

逻辑运算组件

对已经封装好的函数组件的运行结果增加一层封装。

	template <class Predicate>
class unary_negate
: public unary_function <typename Predicate::argument_type, bool>//参数类型是传入Predicate的参数类型,返回类型为bool
{
protected:
Predicate fn;
public:
explicit unary_negate(const Predicate& pred) : fn(pred) {}
bool operator() (const typename Predicate::argument_type& x) const
{
return !fn(x);
}
}; template <class Predicate>
class binary_negate
: public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
{
protected:
Predicate fn;
public:
explicit binary_negate(const Predicate& pred) :fn(pred) {}
bool operator() (const typename Predicate::first_argument_type& x,
const typename Predicate::second_argument_type& y) const
{
return !fn(x, y);
}
};

参数绑定

将要调用的参数保存在结构中,调用的时候再传入

使用typename 和 模板 来指明返回类型 和 参数类型

建议使用explicit来避免隐式类型转换

	template<class Operation>
class binder1st
: public binary_function<typename Operation::first_argument_type, typename Operation::second_argument_type, typename Operation::result_type>
{
protected:
typename Operation::first_argument_type val;//要绑定的参数
Operation op;
public:
explicit binder1st(const Operation& operation, const typename Operation::first_argument_type x) :op(operation),val(x) {}
typename Operation::result_type operator()(const typename Operation::second_argument_type& xs)
{
return op(val, x);
}
}; //绑定第二个参数
template<class Operation>
class binder2nd
: public binary_function<typename Operation::first_argument_type, typename Operation::second_argument_type, typename Operation::result_type>
{
protected:
typename Operation::second_argument_type val;
Operation op;
public:
explicit binder2nd(const Operation& operation, const typename Operation::second_argument_type x) :op(operation),val(x) {}
typename Operation::result_type operator()(const typename Operation::first_argument_type& xs)
{
return op(x, val);
}
};

不定参数的绑定

底层数据 结构用tuple来实现,对于调用参数的获取,维护一个tuple index 模板类,去在模板中递归生成对应下标,这一部分涉及大量的模板元编程。

  • 为什么要生成所有参数的下标?

    需要知道参数的位置,顺序,这样对应着进行模板展开,从tuple中get出对应位置的参数传入函数进行调用
  • 如何生成?

    模板展开 + 模板偏特化
	template <std::size_t...>
struct tuple_indices {}; //生成下标 注意第二个模板是一个类模板 , 第一和第三个模板参数作为展开的边界
template <std::size_t Sp, class IntTuple, std::size_t Ep>
struct make_indices_imp; template <std::size_t Sp, std::size_t... Indices, std::size_t Ep>
struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep>
{
typedef typename make_indices_imp<Sp + 1, tuple_indices<Indices..., Sp>, Ep>::type type;
}; //对结束位置进行特化
template <std::size_t Ep, std::size_t... Indices>
struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep>
{
typedef tuple_indices<Indices...> type;
}; template <std::size_t Ep, std::size_t Sp = 0>
struct make_tuple_indices
{
typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
};

具体tuple的内部实现改天再写。。。

	//绑定不定数目 不定类型的参数
//底层数据通过tuple来保存实现
要实现
template <class F, class... Args>
struct binder
{
//使用std::forward 进行完美转发
//可见 http://en.cppreference.com/w/cpp/utility/forward
binder(F&& f, Args&&... args) :data(std::forward<F>(f), std::forward<Args>(args)...) {}
inline auto operator()()
{
typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, Args...> >::value, 1>::type index_type;
return run2(index_type());
}
template <std::size_t... Indices>
void run2(tuple_indices<Indices...>)
{
//模板展开
invoke(std::move(std::get<0>(data)), std::move(std::get<Indices>(data))...);
}
inline auto invoke(F&& f, Args&&... args)
{
//f 作为函数指针 ,args 作为参数传入
return std::forward<F>(f)(std::forward<Args>(args)...);
}
//使用tuple来保存数据
std::tuple<F,Args...> data;
}; template <class F, class... Args >
ministl::binder<F,Args...> bind(F&& f, Args&&... args)
{
return binder<F, Args...>(std::forward<F>(f), std::forward<Args>(args)...);
}

对类成员函数进行调用

大部分可以用lambda 代替,不过还是写一下,不作重点,精髓还是在于bind

template <class S, class T> mem_fun_t<S, T> mem_fun(S(T::*f)())
{
return mem_fun_t<S, T>(f);
} template <class S, class T, class A>
class mem_fun1_t : public binary_function <T*, A, S>
{
S(T::*pmem)(A);
public:
explicit mem_fun1_t(S(T::*p)(A)) : pmem(p) {}
S operator() (T* p, A x) const
{
return (p->*pmem)(x);
}
}; template <class S, class T, class A> mem_fun1_t<S, T, A> mem_fun(S(T::*f)(A))
{
return mem_fun1_t<S, T, A>(f);
} template <class S, class T>
class const_mem_fun_t : public unary_function <T*, S>
{
S(T::*pmem)() const;
public:
explicit const_mem_fun_t(S(T::*p)() const) : pmem(p) {}
S operator() (T* p) const
{
return (p->*pmem)();
}
}; template <class S, class T> const_mem_fun_t<S, T> mem_fun(S(T::*f)() const)
{
return const_mem_fun_t<S, T>(f);
} template <class S, class T, class A>
class const_mem_fun1_t : public binary_function <T*, A, S>
{
S(T::*pmem)(A) const;
public:
explicit const_mem_fun1_t(S(T::*p)(A) const) : pmem(p) {}
S operator() (T* p, A x) const
{
return (p->*pmem)(x);
}
}; template <class S, class T, class A> const_mem_fun1_t<S, T, A> mem_fun(S(T::*f)(A) const)
{
return const_mem_fun1_t<S, T, A>(f);
} template <class S, class T>
class mem_fun_ref_t : public unary_function <T, S>
{
S(T::*pmem)();
public:
explicit mem_fun_ref_t(S(T::*p)()) : pmem(p) {}
S operator() (T& p) const
{
return (p.*pmem)();
}
};
template<class S,class T,class A>
class mem_fun1_ref_t : public binary_function<T, S, A>
{
S(T::*pmem)(A);
public:
explicit mem_fun1_ref_t(S(T::*p)(A)) :pmem(p) {}
S operator()(T& p, A x) const
{
return (p.*pmem)(x);
}
}; template <class S, class T>
class const_mem_fun_ref_t : public unary_function <T, S>
{
S(T::*pmem)() const;
public:
explicit const_mem_fun_ref_t(S(T::*p)() const) : pmem(p) {}
S operator() (T& p) const
{
return (p.*pmem)();
}
}; template <class S, class T, class A>
class const_mem_fun1_ref_t : public binary_function <T, A, S>
{
S(T::*pmem)(A) const;
public:
explicit const_mem_fun1_ref_t(S(T::*p)(A) const) : pmem(p) {}
S operator() (T& p, A x) const
{
return (p.*pmem)(x);
}
}; //Returns a function object that encapsulates member function f of type T.
template <class S, class T>
mem_fun_ref_t<S, T> mem_fun_ref(S(T::*f)())
{
return mem_fun_ref_t<S, T>(f);
} template <class S, class T, class A>
mem_fun1_ref_t<S, T, A> mem_fun_ref(S(T::*f)(A))
{
return mem_fun1_ref_t<S, T, A>(f);
} template <class S, class T>
const_mem_fun_ref_t<S, T> mem_fun_ref(S(T::*f)() const)
{
return const_mem_fun_ref_t<S, T>(f);
} template <class S, class T, class A>
const_mem_fun1_ref_t<S, T, A> mem_fun_ref(S(T::*f)(A) const)
{
return const_mem_fun1_ref_t<S, T, A>(f);
}

最新文章

  1. React官网学习笔记
  2. 告别我的OI生涯
  3. Kafka集群配置说明
  4. SQLServer 随机生成指定范围的日期
  5. 苹果应用商店DNS修改加快下载速度
  6. Visual Studio 2013
  7. android学习日记13--数据存储之ContentProvide
  8. 单独调用Ueditor的图片上传功能
  9. Java IO之序列化
  10. iOS第三方库-CocoaLumberjack-DDLog (转)
  11. ACdream 1114(莫比乌斯反演)
  12. 【Netty】ChannelHandler和ChannelPipeline
  13. C++windows内核编程笔记day09_day10,对话框和窗体基本控件等的使用
  14. PyCharm介绍与基础操作
  15. Calcite - StreamingSQL
  16. 移动端的rem适配
  17. 如何在Web.config中注册用户控件和自定义控件
  18. maven2中snapshot快照库和release发布库的应用
  19. 七牛云 上传图片 https 修改Nginx 注意事项
  20. C#字典 Dictionary&lt;Tkey,Tvalue&gt; 之线程安全问题 ConcurrentDictionary&lt;Tkey,Tvalue&gt; 多线程字典

热门文章

  1. 谈谈对Android中的消息机制的理解
  2. Linux常用终端快捷键
  3. python中 import 和from ... import 的区别
  4. 使用原生JavaScript模拟getElementByClassName .
  5. react基础语法(三)组件的创建和复合组件
  6. js实现ctrl+v粘贴并上传图片
  7. JQQ文字素材
  8. 暑假集训 || LCA &amp;&amp; RMQ
  9. 【转】解决WPF图片模糊最佳方法(绑定PixelWidth与PixelHeight)
  10. JavaSE-04 Java循环结构