《Essential C++》笔记三(1)、使用泛型算法
2013-09-30 22:34
232 查看
Essential C++第三章主要介绍的是泛型编程风格。
在讲“如何设计泛型算法”时,给出了一个filter的template例子。为了更好的理解和运用泛型算法以及template。将P89(中文版)页给出的sub_vec函数写成template版本。
其原版non-template函数如下:
将其改为template格式后,函数返回一个iterator指针,指针指向find_if找到的第一个大于指定值的元素,函数为:
这样改写是因为,之前的non-template版本与书中改写的filter()函数最大的不一样就是,需要另外开辟空间保证在不改变原数据的顺序的情况下在副本进行排序。而为了增加函数的弹性和扩大函数可用的范围,就不能按照non-template版本那样,通过语句
来建立一个本地的向量。根据Essential C++书中所说,还是采用iterator指针来解决这一问题。虽然这样做可以使函数脱离vector等容器,但走到最后erase一步时,库中没有提供删除的泛型算法,现在还没有想到解决办法,希望知道怎么做的人能留言O(∩_∩)O~。
为了跟书中的filter()函数功能相同,最后加上比较操作,用户可以通过输入比较操作来控制最后留下的数是大于value还是小于value。实现代码如下:
下面贴出测试该函数的main函数代码:
需要注意的是,定义的容器一定要定义容量(vector<int> sub_vector(element_size);),否则在编译时会发生错误,初步认为filter()函数中*at++ = *first++;这句话中自加到最后会指向不明地址,编译器无法通过,所以需要定义容器容量。还需注意的是,返回的指针iter,由于需要erase操作,最好先检测是否指针指到容器最后一个指针。
在讲“如何设计泛型算法”时,给出了一个filter的template例子。为了更好的理解和运用泛型算法以及template。将P89(中文版)页给出的sub_vec函数写成template版本。
其原版non-template函数如下:
vector<int> sub_vec( const vector<int> &vec, int val ) { vector<int> local_vec( vec ); sort ( local_vec.begin(), local_vec.end() ); vector<int>::iterator iter = find_if ( local_vec.begin(), local_vec.end(), bind2nd( greater<int>(), val )); local_vec.erase ( iter, local_vec.end() ); return local_vec; }
将其改为template格式后,函数返回一个iterator指针,指针指向find_if找到的第一个大于指定值的元素,函数为:
//sub_vec的泛型算法 template < typename InputIterator, typename OutputIterator, typename ElemType> OutputIterator sub_vec ( InputIterator first, InputIterator last, OutputIterator at, const ElemType &val ) { OutputIterator at_begin = at; while ( first < last ) *at++ = *first++; OutputIterator at_end = at; sort ( at_begin, at_end ); OutputIterator iter = find_if ( at_begin, at_end, bind2nd ( greater<ElemType>(), val )); return iter; }
这样改写是因为,之前的non-template版本与书中改写的filter()函数最大的不一样就是,需要另外开辟空间保证在不改变原数据的顺序的情况下在副本进行排序。而为了增加函数的弹性和扩大函数可用的范围,就不能按照non-template版本那样,通过语句
vector<int> local_vec( vec );
来建立一个本地的向量。根据Essential C++书中所说,还是采用iterator指针来解决这一问题。虽然这样做可以使函数脱离vector等容器,但走到最后erase一步时,库中没有提供删除的泛型算法,现在还没有想到解决办法,希望知道怎么做的人能留言O(∩_∩)O~。
为了跟书中的filter()函数功能相同,最后加上比较操作,用户可以通过输入比较操作来控制最后留下的数是大于value还是小于value。实现代码如下:
//sub_vec的泛型算法改编的filter()算法 template < typename InputIterator, typename OutputIterator, typename ElemType, typename Comp> OutputIterator filter ( InputIterator first, InputIterator last, OutputIterator at, const ElemType &val, Comp pred ) { OutputIterator at_begin = at; while ( first < last ) *at++ = *first++; OutputIterator at_end = at; sort ( at_begin, at_end, pred ); OutputIterator iter = find_if ( at_begin, at_end, bind2nd ( not2( pred ), val )); return iter; }
下面贴出测试该函数的main函数代码:
int main() { const int element_size = 10; int number[ element_size ] = {32, 54, 22, -23, 78, 99, 0, 698, 10, 2}; vector<int> big_vec ( number, number+element_size ); int value = 10; vector<int> sub_vector( element_size ); cout << "filtering integer array for values less than " << value << endl; vector<int>::iterator iter = filter ( big_vec.begin (), big_vec.end(), sub_vector.begin() , value, less<int>() ); if( iter != sub_vector.end() ) sub_vector.erase( iter , sub_vector.end() ); for ( int ix = 0; ix < sub_vector.size(); ++ix ) cout << "element is : " << sub_vector[ix] << endl; return 0; }
需要注意的是,定义的容器一定要定义容量(vector<int> sub_vector(element_size);),否则在编译时会发生错误,初步认为filter()函数中*at++ = *first++;这句话中自加到最后会指向不明地址,编译器无法通过,所以需要定义容器容量。还需注意的是,返回的指针iter,由于需要erase操作,最好先检测是否指针指到容器最后一个指针。
相关文章推荐
- 《Essential C++》笔记三(3)、使用iostream iterators
- 如何使用C++的泛型算法
- 《Essential C++》笔记三(2)、泛型编程风格
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件【转】
- 《Maven实战》笔记三:使用MyEclipse创建Maven项目
- 使用回调函数实现类型c++的泛型算法
- 《CMake实践》笔记三:构建静态库与动态库 及 如何使用外部共享库和头文件
- C++ 对bitset使用泛型算法
- 硬盘使用误区揭密 PConline
- 重要知识:身份证复印件的正确使用方法
- ASP.NET使用Oralce过程/函数(一)
- 在.net中使用WebBrowser
- showModalDialog()、showModelessDialog()方法使用详解
- C#使用OLEDB读取Excel的一个注意点
- Linux中su命令使用详解
- 使用CMS方法开发功能强大的Web程序
- ASP.NET 2.0使用FCKEditor初體驗
- pagecontrol控件的各种使用方法
- JSP中使用验证码