欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++迭代器作为参数传递进函数使用时的注意事项

程序员文章站 2022-05-25 08:47:54
...

                                    外部函数对迭代器进行值传递而非引用

     需要注意的一点是在使用迭代器作为传入参数进行迭代器运算操作的时候,作用对象仅仅是对传入迭代器的拷贝,因为在传入迭代器后函数直接对传入的对象进行拷贝操作而不访问源对象的内存空间https://blog.csdn.net/hp_truth/article/details/40189291

    因此,如果在外部函数内进行迭代器操作将不会影响主函数内的迭代器对象:

#include<iostream>
#include<vector>
#include<iterator>
#include<typeinfo>


using namespace std;
int main(){
    vector<int> vec={1,2,3,4,5,6,7,8,9,10};
    int element=4;
    auto pltr=begin(vec);
        
    void begin2value(vector<int>::iterator pltr,const int element);//外部函数声明
    begin2value(pltr,element);//调用外部函数

    //检查输出为1,是*(begin(vec))的值
    cout<<(*pltr)<<endl;
    

}
void begin2value(vector<int>::iterator pltr,const int element)//迭代器的值等于需要查找的值,则结束while
{
    while((*pltr)!=element)
        pltr++;
}

明白这点之后,我们还需要注意在传递vector容器时,外部函数内部操作的也是该对象的拷贝。

如果我们要实现一个在外部实现迭代器二分查找的操作而直接向函数传递原来的容器,编译器很可能因为访问越界的内存空间而提示"Segmentation fault",例如:

C++迭代器作为参数传递进函数使用时的注意事项

我们通过使用==运算符来判断两个迭代器是否来自于同一个容器,编译器返回了0,代表在biSearch内部用来创建迭代器的vec只是主函数中vec的一个拷贝,而非引用。通过迭代器距离函数distance来监测两个迭代器之间的距离,距离的输出值为9321038,这部分的内存很可能为操作系统保留或其它进程使用,VSCode直接报异常,以防止程序随意修改该内存中的数据。

       如果我们传入vec的引用,则直接无法通过编译,因为我们不能对vec引用调用相应的容器成员函数begin(),end(),从而无法创建lower、higher。

要使程序通过编译并达到我们想完成的目标,只需要将lower和higher定义在主函数中并作为参数传递,并在函数中将创建的迭代器拷贝返回给真实的迭代器就可以了:

C++迭代器作为参数传递进函数使用时的注意事项

可以看到在主函数内部调用biSearch后将迭代器pltr由原来的begin(vec)移动到了element为4的位置,我们通过使用<typeinfo>头文件下的函数typeid来监测使用传入容器vec构造的迭代器和在主函数创建的迭代器类型是否一致,编译器返回了1。