说到Funtor呢,应该是STL中比较普遍使用的一个东西。大致的意思就是把一个类对象像函数一样的使用,当然这个类需要重载()操作符。因为他比较像函数,所以得了一个Funtor的名字,至于翻译好像主流的叫函数子??有点搞不清状况。
还是看一个最简单的Funtor的例子吧
这个可以看到的是Functor完成了函数一样的工作,但是同时也提供了一些便利的地方,代码符合C++的风格倒是真的。如果能想到的好处可能就是实际上模板函数和模板类的不同,比如我即使用函数,在有的情况的还是不罩的。我没有办法给一个模板函数偏特化,这种情况下当然类就要有优势了。但是没有什么绝对的。另外有些所谓调用性能上的提升,我不敢苟同。也同时觉得现代的应用程序的瓶颈定不在于此。我做了些比如std::sort中的less than的一些自己的实现,并没有发现所谓的雪崩效应,那个comparer functor和compare函数没有什么明显的性能上的差异。这时候的数量级已经到了100000。
说的比较远了,还是回过来继续说这里的Functor的实现,这里的Functor的引出呢是源自与Command这种设计模式。这种模式有效的降低了invoker和receiver之间的联系。这种模式有图为证:
而我们的Functor则成了实现这个Command或者说ConcreteCommand的利器。而且这个书层层递进的解说让人欲罢不能啊:)
首先看看最基本的实现:
可以看见的是这是第一步,就是了解模板的类型参数有哪些,通过字面意思可以理解的是明显的就是返回值和参数,返回值当然就是某个特定的类型ResultType而这个参数就又一次依赖了TypeList。有了这些定义呢,我们已经可以想象到完成之后的调用语句的形状了:) 类似于 Functor<double, TYPELIST_2(int, double)> myFunctor;
当然啦,为了多态等因素的考虑,实际的实现肯定不是这么简单,实际上是吧operate()的调用分发了一个叫FunctorImpl的类来完成的,这个类的定义基本上是这个样子的。
可以看到的是这里的operator()都是以虚函数的形式存在的。同时在Functor类里面的FunctorImpl我们引用了std::auto_prt这个智能指针:
所以这个具体operator的实现呢应该就大致如下,每个functor的()调用实际上都是调用spImpl_对应的()操作符。
其实到这里,基本上我们一个Functor template就完成的七七八八了。当然还有比这个更复杂的东西, 比如说传入的Functor参数不是一个类,而直接是一个函数,我们也应该可以完成调用,就像STL的那些函数一样。由此引来的问题还有如果是一个成员函数是不是也可以捏?好多的为什么:) 这个我们就偷懒一把,浅尝辄止了。。。
还是看一个最简单的Funtor的例子吧
- // test functor class
- template<class T> class plus
- {
- public:
- void operator() (T& aa)
- {
- aa += 10;
- }
- };
- // test function
- template<class T> void c_print( const T& value)
- {
- std::cout<<value<<std::endl;
- }
- int main (void)
- {
- std::vector<int> v;
- v.push_back(10);
- v.push_back(11);
- v.push_back(12);
- for_each(v.begin(), v.end(), plus<int>());
- for_each(v.begin(), v.end(), c_print<int>);
- }
说的比较远了,还是回过来继续说这里的Functor的实现,这里的Functor的引出呢是源自与Command这种设计模式。这种模式有效的降低了invoker和receiver之间的联系。这种模式有图为证:
而我们的Functor则成了实现这个Command或者说ConcreteCommand的利器。而且这个书层层递进的解说让人欲罢不能啊:)
首先看看最基本的实现:
- // Functor with any number and types of arguments
- template <typename ResultType, class TList>
- class Functor
- {
- ...
- };
当然啦,为了多态等因素的考虑,实际的实现肯定不是这么简单,实际上是吧operate()的调用分发了一个叫FunctorImpl的类来完成的,这个类的定义基本上是这个样子的。
- template <typename R>
- class FunctorImpl<R, NullType>
- {
- public:
- virtual R operator()() = 0;
- virtual FunctorImpl* Clone() const = 0;
- virtual ~FunctorImpl() {}
- };
- template <typename R, class TList>
- class Functor
- {
- public:
- ...
- Functor& operator=(const Functor&);
- explicit Functor(std::auto_ptr<Impl> spImpl);
- ...
- private:
- // Handy type definition for the body type
- typedef FunctorImpl<R, TList> Impl;
- std::auto_ptr<Impl> spImpl_;
- };
- R operator()()
- {
- return (*spImpl_)();
- }
- R operator()(Parm1 p1)
- {
- return (*spImpl_)(p1);
- }