这两个概念一般都是一起出现的,今天再次翻起《Ruminations On C++》,这两个概念真的如Koenig所说比较难以理解,加上这次我以前至少也看过了3次了,但是每次都是当时看懂了,过后就忘了,究其原因1:没有真正理解;2没有应用到实际中。 现在暂时也不会应用到实际,但是这次的理解必须写下来。其实函数对象倒还好,一个重载了()了类其对象基本上就可以叫做函数对象,Koenig的说法是:函数对象提供了一种方法,将要调用的函数与准备传递给这个函数的隐式参数捆绑起来。 template<typename _Arg1, typename _Arg2, typename _Result> struct binary_function { typedef _Arg1 first_argument_type; ///< the type of the first argument /// (no surprises here) typedef _Arg2 second_argument_type; ///< the type of the second argument typedef _Result result_type; ///< type of the return type }; template<typename _Tp> struct greater : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; 有了greater我们就可以定义一个对象 greater<int> gt; bool greater1000(int n) { return gt(n,1000);//这里就是调用了greater的operator() } bind2nd可以将一个二元函数对象f(x,y)中的第二个参数y绑定到一个新的一元函数对象上g(x),这时通过g(x)(y)即相当于f(x,y)了,真是妙,这不就是数学里面的复合函数,这次是第一次领悟到这一点,也算是一点进步吧。通过bind2nd的源码可以很清晰得看出其内部机理: template<typename _Operation> class binder2nd : public unary_function<typename _Operation::first_argument_type, typename _Operation::result_type> { protected: _Operation op; typename _Operation::second_argument_type value; public: binder2nd(const _Operation& __x, const typename _Operation::second_argument_type& __y) : op(__x), value(__y) { } //下面的()重载即相当于f(x,y)了,只不过这时的y已经是binder2nd对象的一个成员了,当然f也是起一个成员,这样外部只需传递x了,即将binary转换为unary了。 typename _Operation::result_type operator()(const typename _Operation::first_argument_type& __x) const { return op(__x, value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements typename _Operation::result_type operator()(typename _Operation::first_argument_type& __x) const { return op(__x, value); } } _GLIBCXX_DEPRECATED_ATTR; /// One of the @link s20_3_6_binder binder functors@endlink. template<typename _Operation, typename _Tp> inline binder2nd<_Operation> bind2nd(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::second_argument_type _Arg2_type; return binder2nd01<_Operation>(__fn, _Arg2_type(__x)); } 下面来看看MSDN上面的一个例子: // functional_bind2nd.cpp // compile with: /EHsc #include <vector> #include <functional> #include <algorithm> #include <iostream> using namespace std; // Creation of a user-defined function object // that inherits from the unary_function base class //定义一个一元函数对象,判定传入的参数是否是大于15 class greaterthan15: unary_function<int, bool> { public: result_type operator()(argument_type i) { return (result_type)(i > 15); } }; int main() { vector<int> v1; vector<int>::iterator Iter; int i; for (i = 0; i <= 5; i++) { v1.push_back(5 * i); } cout << "The vector v1 = ( "; for (Iter = v1.begin(); Iter != v1.end(); Iter++) cout << *Iter << " "; cout << ")" << endl; // Count the number of integers > 10 in the vector vector<int>::iterator::difference_type result1a; //将10绑定到新的函数对象binder2nd(greater<int>(),10)上面,接着通过count_if来迭代,并传递参数(*v1.begin()),也就是实现对每一个元素调用greater<int>(*v1.begin(),10) result1a = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 10)); cout << "The number of elements in v1 greater than 10 is: " << result1a << "." << endl; // Compare counting the number of integers > 15 in the vector // with a user-defined function object vector<int>::iterator::difference_type result1b; //这里直接传入一元函数对象 result1b = count_if(v1.begin(), v1.end(), greaterthan15()); cout << "The number of elements in v1 greater than 15 is: " << result1b << "." << endl; // Count the number of integers < 10 in the vector vector<int>::iterator::difference_type result2; //将10绑定到新的函数对象binder2nd(greater<int>(),10)上面,只不过这时10是作为第一个参数绑定的,接着通过count_if来迭代,并传递参数(*v1.begin()),也就是实现对每一个元素调用greater<int>(10,*v1.begin()),也就是比10小的元素个数 result2 = count_if(v1.begin(), v1.end(), bind1st(greater<int>(), 10)); cout << "The number of elements in v1 less than 10 is: " << result2 << "." << endl; }
Function object And Binders
最新推荐文章于 2024-09-26 23:03:56 发布