Tag: STL

STL中const_iterator、reverse_iterator转换为iterator

本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/stl-const-reverse-iterator/ STL中的容器类(Container)一般提供了4个迭代器:iterator、const_iterator、reverse_iterator、const_reverse_iterator,对于 container<T> 而言,其中 const_iterator 相当于 const T *,const_iterator 指向的元素不能做修改操作。 STL 容器的 begin() 和 end() 默认都提供了 iterator 和 const_iterator 的迭代器,相应的 rbegin() 和 rend() 则也分别提供了 reverse_iterator 和 const_reverse_iterator 的迭代器用于从容器的尾端反向遍历。 最近写的代码中刚好要用到 const_iterator 迭代器,发现由于 STL 提供的一些容器操作函数像 insert、erase 的参数必须为 iterator,这时就不能用 const_iterator 做参数(不能直接转换),以下为个人经验结果。 1、const_iterator 转换为 iterator: iterator 可以隐式转换为 const_iterator,但反过来就不行,就算祭出强制类型转换的杀招应该也会编译报错,这是可以用折中的办法解决: vector<sss> v_test; vector<sss>::iterator i_test; vector<sss>::const_iterator c_test; ... c_test = .... ... i_test = v_test.begin(); advance(i_test, distance<vector<sss>::const_iterator>(i_test, c_test)); i_test 指向第一个元素,先通过 distance 得到 c_test 和 i_test 的偏移量,然后用 advance 将 i_test 往后移对应的偏移量即可。注意 distance 的模板类型必须为 const_iterator 类型,否则按照 STL 的默认类型推导,distance 中的 i_test 和 c_test 类型不同还是会出现编译报错。 当然如果你想偷懒简单点,也可以这样写,道理是一样的,这时类型推导就显得很好用了: i_test = v_test.begin() + (c_test - v_test.begin()); 2、reverse_iterator 转换为 iterator: 对于 reverse_iterator 可以调用 base() 得到 “与之对应” 的 iterator(与上面的环境一样): vector<sss> v_test; vector<sss>::iterator i_test; vector<sss>::reverse_iterator r_test; ... r_test = .... ... i_test = r_test.base(); 但需要注意的是由于 STL 的 begin() 和 end()、rbegin() 和 rend() 是两个半闭合的区间,end() 并不是最后一个元素,rend() 也不是第一个元素,因此 end() 和 rbegin()、rend() 和 begin() 之间都是差了一个元素的。我们来看看 STL 标准上 base() 的说明: The base iterator is an iterator of the same type as the...

bind2nd普通二元函数时无法使用引用类型参数的问题

本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/cplusplus-bind2nd-reference/ 在使用 STL 的 find_if、count_if 等函数时会发现这些函数使用的参数不是普通的函数指针,而是 functional 函数对象,实际使用函数对象时可以自己定义一个仿函数来实现(实现带参数的 operator () 即可),这个相对比较简单就不写出来了。但有些情况需要直接使用普通的二元函数指针,这时可以使用 ptr_fun 将函数指针转换为函数对象作为 find_if、count_if 等的参数。 先看一个能正常工作的二元函数不使用引用类型参数的代码: 程序很简单,从 vector 中查找符合条件的 sss 对象,find_sss 就是要转换的二元函数指针,第一个参数是 sss 类,通过 ptr_fun 可以使本代码正常工作。 通过下面的运行输出能看出调用 find_sss 时进行了拷贝构造(本程序的编译环境为:Windows 7 32bit, Mingw gcc 3.4.5,Visual Studio 2010中稍有不同,主要在前面的拷贝次数上): ---copy 0x22ff10 to 0x552a58 ---copy 0x552a58 to 0x552ad8 ---copy 0x22ff10 to 0x552ae0 ---copy 0x552ad8 to 0x552af0 ---copy 0x552ae0 to 0x552af8 ---copy 0x22ff10 to 0x552b00 ---copy 0x22ff10 to 0x552b08 ---copy 0x552af0 to 0x552b18 ---copy 0x552af8 to 0x552b20 ---copy 0x552b00 to 0x552b28 ---copy 0x552b08 to 0x552b30 ---copy 0x22ff10 to 0x552b38 before find_if ---copy 0x552b18 to 0x22fdd0 ---copy 0x22fdd0 to 0x22fd40 ---copy 0x552b20 to 0x22fdd0 ---copy 0x22fdd0 to 0x22fd40 ---copy 0x552b28 to 0x22fdd0 ---copy 0x22fdd0 to 0x22fd40 index: 2, value: 13 接下来就是实际碰到的问题了,如果将 find_sss 的第一个参数改为 sss 的引用,即第 24 行改为: bool find_sss(sss& s_chk, int val) 上面的代码就会编译出错(以 Visual Studio 2010 的错误输出为例): C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xfunctional(341) : error C2535: “bool std::binder2nd<_Fn2>::operator ()(sss &) const”: 已经定义或声明成员函数 with [ _Fn2=std::pointer_to_binary_function<sss &,int,bool,bool (__cdecl...

vector的push_back拷贝构造和空间占用分析

本文同步自:https://zohead.com/archives/vector-push-back-space-copy/ 这两天在实际程序中使用 STL 的 vector push_back 类对象时出现问题,偶尔发现 vector 在 push_back 时的调用类对象的拷贝构造函数和析构函数有点特别,简单做下分析。 程序代码: 功能很简单,main 中定义一个 sss 类对象和对应的 vector,然后在循环中改类成员的值,并依次 push_back 到 vector 中,类的构造函数、析构函数、拷贝构造函数中都加了对应的打印输出。循环运行了5次,往 vector 中增加了5个类成员。 实际运行输出如下: ---init sss 0x22ff20, value:11 ---copy 0x22ff20 to 0x5d2a58 size: 1, capacity: 1 ---copy 0x5d2a58 to 0x5d2ad8 ---copy 0x22ff20 to 0x5d2adc ---destory sss 0x5d2a58, value:12 size: 2, capacity: 2 ---copy 0x5d2ad8 to 0x5d2ae8 ---copy 0x5d2adc to 0x5d2aec ---copy 0x22ff20 to 0x5d2af0 ---destory sss 0x5d2ad8, value:12 ---destory sss 0x5d2adc, value:13 size: 3, capacity: 4 ---copy 0x22ff20 to 0x5d2af4 size: 4, capacity: 4 ---copy 0x5d2ae8 to 0x5d2b00 ---copy 0x5d2aec to 0x5d2b04 ---copy 0x5d2af0 to 0x5d2b08 ---copy 0x5d2af4 to 0x5d2b0c ---copy 0x22ff20 to 0x5d2b10 ---destory sss 0x5d2ae8, value:12 ---destory sss 0x5d2aec, value:13 ---destory sss 0x5d2af0, value:14 ---destory sss 0x5d2af4, value:15 size: 5, capacity: 8 ---destory sss 0x5d2b00, value:12 ---destory sss 0x5d2b04, value:13 ---destory sss 0x5d2b08, value:14 ---destory sss 0x5d2b0c, value:15 ---destory sss 0x5d2b10, value:16 ---destory sss 0x22ff20, value:16 结果分析: vector...