2016-05-20 45 views
3

我有一個向量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); 

需要幫助。

+0

你爲什麼要這個指針?你可以index = std :: distance(v.begin(),i1);返回(&v [ix]) – thorsan

+1

或者使用std :: find(v.begin(),v.end(),a) – thorsan

回答

9

這將解決你的問題:

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) 
} 
+0

你不需要這些圓括號,前綴運算符是從左到右解析的。 '&(* it)'與'&* it'相同。 –

+1

如果向量中沒有元素,則會將結束迭代器轉換爲指針。不能保證它會指向一個超過矢量存儲結尾的位置。如果沒有找到元素,函數應該檢查這個並返回'nullptr'。 – NathanOliver

+0

@NathanOliver是的謝謝 –

1

你可以做這樣的事情

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; 
} 
0

使用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; 
}