开发者社区> 问答> 正文

c++ 编写类似于标准库中find算法的模板,非引用形参和引用形参的区别是什么

#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename Init,typename T> Init find(Init begin,Init end,const T& val){
    while(begin!=end){
        if(val==(*begin)){
            return begin;
        }
        ++begin;
    }
    return end;
}
//为什么前2个参数改成引用就不行了
template<typename Init,typename T> Init find_(Init &begin,Init &end,const T& val){
    while(begin!=end){
        if(val==(*begin)){
            return begin;
        }
        ++begin;
    }
    return end;
}

int main(){
    int arr[5] = {1,2,3,45,5};
    string sarr[5] = {"b","c ","dd","ee","ff"};
    vector<int> ivec(arr,arr+5);
    vector<string> svec(sarr,sarr+5);
    vector<int>::iterator it;
    vector<string>::iterator sit;
    if((it=find(ivec.begin(),ivec.end(),3))!=ivec.end()){
        cout << *it << "is in the vector" << endl;
    }else{
        cout << "not found!" << endl;
    }
    if((sit = fd_(svec.begin(),svec.end(),string("b")))!=svec.end()){
        cout << "find" << endl;
    }
    else{
        cout << "not find";
    }
}

把find函数的前两个形参改成引用,会产生编译错误,为什么
error: invalid initialization of non-const reference of type ‘__gnu_cxx::__normal_iterator, std::vector >&’ from an rvalue of type ‘std::vector::iterator {aka __gnu_cxx::__normal_iterator, std::vector >}’

 if((it=find_(ivec.begin(),ivec.end(),3))!=ivec.end()){
                                       ^

error: in passing argument 1 of ‘Init find_(Init&, Init&, const T&) [with Init = __gnu_cxx::__normal_iterator >; T = int]’
template Init find_(Init &begin,Init &end,const T& val){

展开
收起
a123456678 2016-03-05 09:38:10 3265 0
3 条回答
写回答
取消 提交回答
  • 乐于学习与分析

    vector::iterator begin = svec.begin();
    vector::iterator end = svec.end();
    if((sit = find_(begin,end,string("b")))!=svec.end()){

    cout << "find" << endl;

    }
    else{

    cout << "not find";

    }
    1、看代码

    2、编译结果

    3、分析和解决
    就拿f(a + b)来说,a+b的值会存在一个临时变量中,当把这个临时变量传给f时,由于f的声明中,参数是int&,不是常量引用,因为c++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制。

    修改:

    或则函数参数引用加上const

    4、总结
    c++中临时变量不能作为非const的引用参数

    2019-07-17 18:52:56
    赞同 展开评论 打赏
  • 软件开发,安全加密

    vector::iterator begin = svec.begin();
    vector::iterator end = svec.end();
    if((sit = find_(begin,end,string("b")))!=svec.end()){

    cout << "find" << endl;

    }
    else{

    cout << "not find";

    }
    1、看代码

    2、编译结果

    3、分析和解决
    就拿f(a + b)来说,a+b的值会存在一个临时变量中,当把这个临时变量传给f时,由于f的声明中,参数是int&,不是常量引用,因为c++编译器的一个关于语义的限制。如果一个参数是以非const引用传入,c++编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。但如果你把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以,一般说来,修改一个临时变量是毫无意义的,据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制。

    修改:

    或则函数参数引用加上const

    4、总结
    c++中临时变量不能作为非const的引用参数

    2019-07-17 18:52:56
    赞同 展开评论 打赏
  • 正确代码如下:

    if((it=find(ivec.begin(),ivec.end(),3))!=ivec.end()){
    cout << it << "is in the vector" << endl;
    }else{
    cout << "not found!" << endl;
    }
    **if((sit = fd_(svec.begin(),svec.end(),string("b")))!=svec.end()){
    cout << "find" << endl;
    }* 
    else{
    cout << "not find";
    }
    2019-07-17 18:52:56
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
数据+算法定义新世界 立即下载
袋鼠云基于实时计算的反黄牛算法 立即下载
Alink:基于Apache Flink的算法平台 立即下载