【问题标题】:converting vector iterator to pointer将向量迭代器转换为指针
【发布时间】:2016-09-17 16:15:47
【问题描述】:

我有一个向量 std::vector。我想迭代向量以找到匹配项,如果找到想要返回指向元素的指针,如下所示:

const int * findint(std::vector <int> &v, int a)
{
        std::vector<int>::const_iterator i1,i2;
        i1 = v.begin();
        i2 = v.end();
        for(;i1 != i2;++i1) {
                if(a== *i1) {
                        return(i1);
                }
        }
        return(0);
}

使用 GNU g++2.95.3 编译器编译和工作正常,但使用 GNU g++ 4.9.2 编译不正常,并给出以下错误:

error: cannot convert 'std::vector<GenFld>::const_iterator {aka __gnu_cxx::__normal_iterator<const int*, std::vector<int> >}' to 'const int*' in return
     [exec]     return(i1);

需要帮助。

【问题讨论】:

  • 为什么要指针?您可以 index = std::distance(v.begin(), i1);返回(&v[ix])
  • 或者使用 std::find(v.begin(), v.end(), a)

标签: c++ pointers c++11 vector iterator


【解决方案1】:

使用v.data():

const int * findint(const std::vector <int> &v, int a)
{
  const int * const b = v.data();
  const int * const e = b + v.size();
  const int * const r = std::find(b, e, a);
  return (r == e) ? nullptr : r;
}

【讨论】:

    【解决方案2】:

    这将解决您的问题:

    const int * findint(const std::vector <int> &v, int a){
        auto i1 = v.cbegin();
        auto i2 = v.cend();
        for(;i1 != i2;++i1){
            if(a == *i1){
                return &*i1;
            }
        }
        return nullptr;
    }
    

    编辑:请注意,我将迭代器更改为cbegincendvector 现在也作为const 传递。

    但是,IMO 的正确做法(关于nathanoliver 注意):

    auto it = std::find(v.cbegin(),v.cend(),value);
    decltype(&*it) ptr;
    if(it==v.cend()){
        ptr = nullptr;
    }
    else{
        ptr = &*it;
    }
    

    使用它时必须小心。在向量上的任何push_backinserterase 之后,指针和迭代器可能无效,有关完整列表,请参阅Iterator invalidation rules。如果您想保留线索以稍后到达某些项目。如果您可以保证只会添加到向量的后面,您可以使用以下方式保留项目的索引:

    auto it = std::find(v.cbegin(),v.cend(),value);
    size_t index;;
    if(it==v.cend()){
        //do something
    }
    else{
       index = std::distance(v.cbegin(),it)
    }
    

    【讨论】:

    • 你不需要那些括号,前缀运算符是从左到右解析的。 &amp;(*it)&amp;*it 相同。
    • 如果向量中没有元素,这会将结束迭代器转换为指针。无法保证它会指向向量存储结束后的位置。如果没有找到元素,该函数应该检查并返回nullptr
    【解决方案3】:

    你可以这样做

    auto i1 = std::find(v.begin(), v.end(), a);
    if(i1 != v.end())
    {
        index = std::distance(v.begin(), i1); 
        return(&v[index])
    }
    else
    {
        return NULL;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 2018-05-30
      • 2014-10-13
      • 1970-01-01
      相关资源
      最近更新 更多