7
votes

Recherche vecteur C ++ std des structures pour la structure avec une chaîne correspondante

Je suis sûr que je rendais cela plus difficile qu'il ne doit être.

J'ai un vecteur ... xxx

... comprenant des structures À motifs après ce qui suit: xxx

J'essaie de chercher mjointsvector avec "std :: trouver" pour localiser un joint individuel par son nom de chaîne - sans chance jusqu'à présent, mais Les exemples des éléments suivants ont aidé, au moins conceptuellement:

vecteurs, structures et std :: Trouver

Quelqu'un peut-il me dire plus loin dans la bonne direction?


3 commentaires

Bien que les réponses ci-dessous soient bien et bonnes, votre utilisation sonne comme si vous devriez utiliser un plan à partir de chaîne à joints . Cela améliorera également vos temps de recherche.


Je pense que vous avez probablement raison - je vais devoir regarder cela plus tard.


WOW, cartes et multimaps sont super! Surtout avec pour_achise Utilisation d'objets de fonction au lieu de boucles! codeProject.com/kb/stl/replace_for_for_ach.aspx?display=pri NT si utile de pouvoir "réutiliser" le code de la boucle de cette façon.


6 Réponses :


16
votes

Une approche directe: xxx

Vous pouvez également regarder dans quelque chose comme BOOST.Bind Pour réduire la quantité de code.


4 commentaires

Bien que cela fonctionne, je pense que l'opérateur () d'un objet de fonction devrait toujours être constitué, juste pour la flexibilité. Si un jour où vous avez une gamme de joints constants, l'objet de fonction fonctionne toujours.


Cela semble ne semble fonctionner que si je change "Opérateur Bool (" "Opérateur BOOL () (". Est-ce correct? Je suis submergé par combien de façons de faire cela!


Oups, j'ai raté les premières parenthèses - corrigé.


@Vivivivivos: il fonctionne déjà avec Cons-joints - Je suis d'accord sur la Constance.



0
votes
bool
operator == (const Joints& joints, const std::string& name) {
    return joints.name == name;
}

std::find(mJointsVector.begin(), mJointsVector.end(), std::string("foo"));

0 commentaires

1
votes

Vous devriez pouvoir ajouter un opérateur égal à votre structure xxx

puis vous pouvez rechercher à l'aide de la recherche.


3 commentaires

L'exploitant d'égalité doit être réservé pour être utilisé pour tester si deux objets du même type sont équivalents. Seulement très rarement si vous l'utilisez pour comparer avec d'autres types.


Esprit expliquant pourquoi ou citer une source qui fait?


Cette réponse courte simplifie a de nombreux courts-livres: vous devez préférer les opérateurs de fonction libres sur les opérateurs de fonctions membres (symétrie par rapport aux types dans certaines opérations), si vous surchargez == Vous devez également surcharger! =, Et enfin comme martin pointé, lorsque vous surchargez un Opérateur, vous ne devriez pas changer la sémantique. Le symbole de l'opérateur implique une certaine sémantique au lecteur, si ces sémantiques sont cassées la possibilité d'erreurs dans les augmentations de code d'utilisateur. Qui pourrait penser que a == b donnerait vrai pour différents objets?



5
votes

Que diriez-vous:

std::string name = "xxx";

std::find_if(mJointsVector.begin(), 
             mJointsVector.end(), 
             [&s = name](const Joints& j) -> bool { return s == j.name; }); 


13 commentaires

Quoi? Ce n'est pas encore supporté: P (Même alors, je pense que c'est faux.)


Ce n'est pas faux, c'est correct et dans quelques années, cette réponse sera considérée comme «plus» correcte par rapport aux autres.


Darid, que voulez-vous dire? Pourquoi est-ce plus correct? Pas vous défier - je suis totalement désemparé en fait - et curieux.


@darid: Ne modifiez pas votre réponse alors réfute ma déclaration! : P c'est comme une paille virtuelle. C'était faux, mais maintenant c'est certainement bon. :]


@Monte: Les autres réponses sont ce que vous devez faire aujourd'hui. Cette fonctionnalité, appelée "Lambdas", sont des fonctions fondamentalement sur place. En substance, ils créent des foncteurs sans nom, semblables aux autres réponses. Mais cela conserve la logique proche du site d'appel et est sans doute plus lisible.


Bien que la fonction anonyme soit une bonne idée, ne devriez-vous pas utiliser wind_if ?


Il est pris en charge par les compilateurs d'Intel (Lambdas, je n'ai pas testé celui-ci) et semble faux: l'argument doit être const joint & et la comparaison doit probablement être nom! = S.Name , et il devrait être wind_if


@Gman: Jeeeez Vous êtes trop rapide pour moi, j'espérais aller sous le radar avec cette modification:>


@Dribeas: (1) Le type est des joints non joints (2) La comparaison est correcte - Veuillez lire le code (3) en général, il s'agit de la direction C ++, les gens doivent commencer à utiliser ces fonctionnalités au lieu de surplancher avec VC6, VC8 , Compilateurs VC9 Gen.


Donc, le soutien de Lambda n'est pas assez omniprésent? Quelqu'un peut-il me dire s'ils sont prudents à utiliser avec des projets OS X 10.6 ou iPhone?


J'ai raté votre code édité en lisant certaines des autres réponses, vous avez donc raison dans les articulations et la comparaison est correcte maintenant. Pourtant, il devrait être wind_if au lieu de trouver et je ne suis pas sûr que la syntaxe que vous utilisez pour capturer la variable nom est vrai. Peut-être: STD :: Find_IF (..., [& Name] (const Joints & j) -> ...) ?


@Monte: c'est une fonctionnalité qui sera dans la norme NEXT C ++ qui n'est pas encore sortie. Les versions actuelles du GCC le prennent en charge lors de la définition d'un drapeau, Visual Studio 2010 les prendra également en charge.


@Monte: Si vous pouvez utiliser g ++ 4.5 ou plus tard, vous pouvez essayer, mais G ++ 4.4 et avant de n'avoir pas de support Lambda. Et là encore, je ne voudrais pas essayer le dernier addition dans le compilateur pour le code de production tant que quelque temps et les tests ont été effectués.



0
votes
struct Compare: public unary_function <const string&>
{
     public:
            Compare(string _findString):mfindString(_findString){}
            bool operator () (string _currString)
            {
                return _currString == mfindString ;
            }
     private:
            string mfindString ;
}

std::find_if(mJointsVector.begin(), mJointsVector.end(), Compare("urstring")) ;

1 commentaires

Vous n'avez jamais déclaré _curtring ou _Findstring et votre héritage est incorrect (précisez les paramètres de modèle)



1
votes
#include <boost/bind.hpp>

std::vector<Joints>::iterator it;

it = std::find_if(mJointsVector.begin(),
                  mJointsVector.end(),
                  boost::bind(&Joints::name, _1) == name_to_find);

0 commentaires