博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小论C++函数对象在STL算法函数中的应用
阅读量:5731 次
发布时间:2019-06-18

本文共 4366 字,大约阅读时间需要 14 分钟。

  hot3.png

  • 函数指针作为传入参数:

C++中函数名的本质为指向函数的指针,可以被传递到接受方法指针作为参数的函数中去,这在不少STL算法函数的可选参数中有所体现。

以常用的一个算法函数binary_search为例,在C++ reference中,可以查得它的两个传入参数分别如下:

template< class ForwardIt, class T >bool binary_search( ForwardIt first, ForwardIt last, const T& value );template< class ForwardIt, class T, class Compare >bool binary_search( ForwardIt first, ForwardIt last, const T& value, Compare comp );

这说明binary_search这个函数除了接受两个迭代和一个参数作为传入参数之外,还可以接受comp作为参数,其有两个重载了同一个函数名的函数。因此,如果在一个正序以及倒序排序的序列中查找某个元素,就分别要用到这两个不同版本的重载函数,代码的示例如下:

#include 
#include
#include
#include
using namespace std;bool compare(int num1, int num2){ return num1 > num2; }int main(int argc, char** argv) { vector
intV1 = {1, 3, 5, 7, 9}; vector
intV2 = {9, 7, 5, 3, 1}; //Searching in ascending order: bool is5Exist = binary_search(intV1.cbegin(), intV1.cend(), 5); cout << "Element 5 " << (is5Exist ? "exsits" : "does not exist") << " in int vector 1. " << endl; //Searching in descending order, need to specify the descending order: is5Exist = binary_search(intV2.cbegin(), intV2.cend(), 5, compare); cout << "Element 5 " << (is5Exist ? "exsits" : "does not exist") << " in int vector 2. " << endl; return 0;}

输入图片说明

上述代码中,compare就作为函数指针在对第二个vector进行搜索时作为传入参数。然而,除了函数指针能够作为传入参数,函数对象作为指针对应的地址,也能参与传入。此外,lambda表达式也可传入。本文重点介绍函数对象的传入机制。

  • 用户定义的函数对象作为传入参数:

由于指针事实上对应地址,因此Compare参数接受的参数还可以是类或者结构体。举例如下:

class CompareEle{public:    bool operator()(int num1, int num2){ return num1 > num2;}};struct CompareNum{    bool operator()(int num1, int num2){ return num1 > num2;}};

对于上述类和结构体的调用大体是相同的,举例如下:

//调用用类声明的比较:is5Exist = binary_search(intV2.cbegin(), intV2.cend(), 5, CompareEle());//调用用结构体声明的比较:is5Exist = binary_search(intV2.cbegin(), intV2.cend(), 5, CompareNum());

此处,在类或者结构体中重写了方法调用函数,即bool operator(),即定义了用户定义的比较不同元素之间的方式。

  • STL自带函数对象作为传入参数:

由上述例子可见,函数对象的应用还是非常广泛的。考虑到这点,C++的标准模版库中已经储备了一些常用的函数对象,如下面例子中的std::greater。更多这样的函数对象,详情可以参见参考资料3。因此,上述在第二个vector中搜索元素5的调用还可以书写如下:

is5Exist = binary_search(intV2.cbegin(), intV2.cend(), 5, std::greater
());
  • 总结比较:

本文简单介绍了C++函数指针、函数对象的概念以及函数指针和函数对象在标准模版库中的几种使用方式。由于C++的编译器通常能对函数对象(也即类或结构体书写的重载方法调用函数)作出优化,因此更加推荐在编程中使用函数对象或者C++ STL自带的函数对象声明对象之间的关系。此外,自定义的函数指针和函数对象返回值也不仅仅限于bool,还可以是其他形式。比如参考资料4的第554页就给出了如下例子:

#include 
#include
#include
#include
#include
// array class-template definition#include
// copy algorithm#include
// accumulate algorithm#include
// binary_function definition#include
// ostream_iteratorusing namespace std;// binary function adds square of its second argument and the// running total in its first argument, then returns the sum int sumSquares( int total, int value ) { return total + value * value; } // end function sumSquares// Class template SumSquaresClass defines overloaded operator()// that adds the square of its second argument and running // total in its first argument, then returns sum template< typename T > class SumSquaresClass {public: // add square of value to total and return result T operator()( const T &total, const T &value ) { return total + value * value; } // end function operator()}; // end class SumSquaresClassint main(){ const size_t SIZE = 10; array< int, SIZE > integers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; ostream_iterator< int > output( cout, " " ); cout << "array integers contains:\n"; copy( integers.cbegin(), integers.cend(), output ); // calculate sum of squares of elements of array integers // using binary function sumSquares int result = accumulate( integers.cbegin(), integers.cend(), 0, sumSquares ); cout << "\n\nSum of squares of elements in integers using " << "binary\nfunction sumSquares: " << result; // calculate sum of squares of elements of array integers // using binary function object result = accumulate( integers.cbegin(), integers.cend(), 0, SumSquaresClass< int >() ); cout << "\n\nSum of squares of elements in integers using " << "binary\nfunction object of type " << "SumSquaresClass< int >: " << result << endl;} // end main

此处,用户定义的函数指针和函数对象返回值分别为int和T,定义了计算求和的方式,这种用法值得参考学习。

参考资料:

  1. binary_search的使用参考,URL:
  2. chengyang的博客,URL:
  3. 函数对象参考资料,URL:
  4. Paul Deitel & Harvey Deitel, 《C++11程序设计(英文版)(第2版)》,2016年4月,电子工业出版社

转载于:https://my.oschina.net/Samyan/blog/878125

你可能感兴趣的文章
iOS - Regex 正则表达式
查看>>
SYS_CONTEXT函数返回IP地址的一些误解
查看>>
第 68 章 Logical Volume Manager (LVM)
查看>>
膝盖中了一箭之康复篇-第八个月暨2月份目标总结
查看>>
IPA提交APPStore问题记录(一)
查看>>
有利于seo优化的网站地图不能取巧
查看>>
快照产品体验优化
查看>>
ASCII
查看>>
50天!3家!共享单车终于开始了“大逃亡”
查看>>
ibatis SqlMap not found
查看>>
Android SD卡创建文件和文件夹失败
查看>>
Ubuntu 14.04 vsftp refusing to run with writable root inside chroot问题解决方法
查看>>
Intellij IDEA远程调试tomcat
查看>>
hadoop的学习论坛
查看>>
替代Windows Cmd的利器PowerCmd
查看>>
Struts2 学习小结
查看>>
Linux IPMI 安装配置实用
查看>>
烂泥:wordpress迁移到docker
查看>>
.扒渣机的性能及优势 
查看>>
Linux下磁盘保留空间的调整,解决df看到的空间和实际磁盘大小不一致的问题
查看>>