2009-10-27 4 views
4

Aujourd'hui, j'ai écrit un petit prédicat pour trouver des symboles correspondants dans un conteneur.Algorithmes STL et const_iterators

Mais je suis confronté à un problème: je veux utiliser ce prédicat dans un appel std::find_if à l'intérieur d'une const-méthode d'une classe, la recherche dans un conteneur qui est membre de cette classe.

Mais je viens de remarquer que ni std::find ni std::find_if ne peuvent fonctionner sur const_iterators! J'ai vérifié sur certaines références C++ et il semble qu'il n'y ait pas de version de std::find ou std::find_if qui accepte/retourne const_iterators Je ne comprends tout simplement pas pourquoi, d'après ce que j'ai vu, il n'y a aucun moyen que ces algorithmes puissent modifier l'objet référencé par l'itérateur.

Voici comment est documenté std::find dans la mise en œuvre SGI:

Renvoie le premier itérateur i dans la gamme [first, last) de telle sorte que * i == valeur. Renvoie en dernier si aucun itérateur n'existe.

+0

Quelle est l'erreur réelle que vous obtenez? Pouvez-vous également poster un exemple de code? Merci –

+2

En fait, vous venez de mal lire la documentation, voir la réponse de Pavel ci-dessous. Si vous testez, vous verrez que cela fonctionne définitivement. –

+0

Votre question implique que vous avez un code qui ne fonctionne pas - en particulier "Mais je suis confronté à un problème" - alors que vous pensez tout simplement à haute voix. J'ai downvoted cette question parce que si vous l'aviez essayé, vous l'auriez vu fonctionner. –

Répondre

13

std::find et std::find_if peut certainement fonctionner sur *::const_iterator pour un conteneur donné. Êtes-vous par hasard en regardant les signatures de ces fonctions, et les malentendu?

template <class InputIterator, class Type> 
InputIterator find(InputIterator first, InputIterator last, const Type& val); 

Notez que InputIterator ici est juste un nom d'un paramètre de type de modèle, et tout const_iterator satisfera aux exigences pour elle.

Ou, peut-être, vous confondez const_iterator (à savoir un itérateur faisant référence à une valeur const) avec un const iterator (à savoir un itérateur qui est lui-même const)?

+0

Oh, je suppose qu'il est trop tard, je viens de marcher sur des dizaines de documents et chaque fois que j'ai lu ce que je voulais, pas ce qui était écrit x ( Merci pour votre patience. – NewbiZ

5

std::find et std::find_if les deux prennent le type iterator comme paramètre de modèle, ils peuvent certainement fonctionner sur const_iterators. Juste un exemple rapide:

#include <vector> 
#include <algorithm> 
#include <iostream> 
int main() { 
    std::vector<int> x; 

    std::fill_n(std::back_inserter(x), 20, 2); 
    x.push_back(3); 

    std::vector<int>::const_iterator b = x.begin(); 
    std::vector<int>::const_iterator e = x.end(); 

    std::vector<int>::const_iterator p = std::find(b, e, 3); 

    std::cout << *p << " found at position: " << std::distance(b, p) << "\n"; 
    return 0; 
} 

Cela devrait être accepté par tout fonctionne correctement compilateur C++, et produire des résultats tels que:

3 trouvé à la position: 20

1

Je viens d'avoir le même problème . J'avais une fonction membre qui appelait find_if sur un vecteur membre, et le compilateur m'a donné une erreur lorsque j'ai essayé de faire la fonction membre const. Il s'est avéré que c'était parce que j'assignais la valeur de retour de find_if à iterator au lieu de const_iterator. Le compilateur a supposé que les paramètres de find_if devaient également être iterator au lieu de const_iterator, ce qu'il ne pouvait pas obtenir du vecteur membre const.

0

Si par hasard vous êtes ici pour la même raison que moi:

error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’ 

Il n'a rien à voir avec const_iterator s. Vous avez probablement juste oublié de #include <algorithm> :-)

0

Je viens d'avoir un problème avec ce code:

std::string str; 
std::string::const_iterator start = str.begin(); 
std::string::const_iterator match = std::find(start, str.end(), 'x'); 

L'erreur était « pas de surcharge correspondant pour std :: trouver ».

Le correctif dont j'avais besoin était d'utiliser cend(). Il est déroutant que cbegin() ne soit pas nécessaire, je ne suis pas sûr de savoir pourquoi cette conversion est correcte (implicitement) et pas pour la fonction end() en tant que paramètre de fonction.