J'ai un Le comportement simplement itération sur la boucle serait: P> std :: vecteur code> de Pointeurs
Personne code> d'objets, qui ont une fonction de membre
std :: string getname () const code>. Utilisation d'algorithmes STL, je veux compter toutes les objets code> de la personne code> dans le vecteur où
getname () code> retourne "Tchad".
const int num_chads = std::count_if(vec.begin(), vec.end(),
std::bind1st(std::bind2nd(std::equal_to, mem_fun(Person::getName)), "Chad"));
3 Réponses :
J'ai toujours trouvé Lambdas relativement illisible. Je préfère beaucoup écrire des types explicites: bien que la définition de nommée code> est "hors ligne", un nom correctement choisi transmet l'intention et cache la Détails d'implémentation. Personnellement, je considère cela une bonne chose, car alors je ne dis pas les détails de la mise en œuvre ni d'essayer de comprendre ce qui se passe en ingénierie inverse du code (aussi évident que cela pourrait être). P> P>
C'est une bonne solution, mais personnellement, je vois des foncteurs utilisés pour cela comme la Lambda de l'homme pauvre, principalement en raison du code de la plaque de chaudière impliqué.
@stefaanv: Je suis d'accord avec la chaudière, mais puisque nous utilisons une nommée pour avoir une intention, des fonctions anonymes n'ont pas ce niveau d'explicité, bien sûr, pour de telles fonctions simples, on pourrait affirmer que c'est évident ... Cependant la syntaxe d'arcanes de STD :: BIND * code> cache la simplicité.
Oui, c'est une bonne solution pour équilibrer une approche plus fonctionnelle sans curryer les foncteurs de la STL. Cependant, je cherchais vraiment quelque chose qui n'a pas impliqué d'écrire vos propres objets de fonction (je sais que cela n'a pas été spécifié dans la question). Cela dit, clairement un bon exemple d'utilisation d'un prédicat personnalisé dans le comte_if.
Mais, peut-il nommé code> être déclaré dans la même fonction dans laquelle il est utilisé? Chaque fois que j'essaie, je reçois des erreurs de portée.
Je pense "Taille_t const c = std :: comte_if (Vec.begin (), Vec.end (), [] (const personne & p) {retour p.getname () ==" Tchad ";});" Est toujours bien, mais cela devient probablement rapidement plus compliqué.
@ROB Adams: Malheureusement, je suggère des espaces de noms anonymes. La norme C ++ 03 interdit en réalité l'utilisation de types définis sur la fonction sous forme de paramètres de modèle (je pense que c'est un problème de lien, mais vous aurez besoin de quelqu'un de plus savant que moi pour une confirmation).
@stefaanv: True Lambdas sont assez lisibles, je suis d'accord, mais l'OP spécifié qu'il souhaitait une solution C ++ 03 et, malheureusement, je ne peux pas penser à une solution élégante avec Bind code> (quelle que soit la version). J'aimerais vraiment que Deadmg augmente sa réponse pour voir la syntaxe qu'il avait à l'esprit.
@Rob - Cette réponse manque des informations pour des raisons de brièveté. Nommé est une structure, ce qui signifie qu'il ne peut être défini que dans une autre définition de classe ou comme une structure seule (ceci s'applique aux classes également). Vous ne pouvez pas définir une classe à l'intérieur d'une fonction, qui a toujours été l'un des plus gros problèmes de l'utilisation des foncteurs personnalisés: ils doivent être définis à l'écart du point qu'ils sont appelés. C'est là que les lambas entrent et rendent les choses plus attrayantes en vous laissant définir efficacement une fonction dans une autre.
L'approche est juste, mais la mise en œuvre n'est pas. À l'intérieur du fonctionnement, vous stockez un pointeur à un littéral et comparant ce pointeur avec le résultat d'un appel à la fonction getname () code>, qui ne sera probablement pas un pointeur sur le même littéral à chaîne.
@David: Nope, en fait, selon ma remarque, il renvoie un std :: string code> (par copie).
Utiliser boost :: lid code>, il est supérieur d'une manière tout à fait une manière aux mécanismes de liaison standard existants.
boost :: lid code> est complètement C ++ 03 compatible. p>
Pouvez-vous penser à une façon de le faire sans booster?
Ou, sinon, fournir une réponse de boost? (Ou les deux!: P)
@Rodion Ingles: Bien sûr, mais cela impliquerait juste écrire boost :: lid code> à nouveau vous-même, ce qui est plutôt inutile. En ce qui concerne la fourniture d'une telle réponse, la documentation est parfaitement suffisante pour que vous puissiez le faire vous-même. C'est le travail de la réponse à vous aider, pas de votre main.
Eh bien, peut-être que vous avez un point sur la fourniture d'un exemple de boost, mais votre TRITE répondit de "Écriture boost :: lidez-vous à nouveau" ne servent personne mais vous.
@Rodion Ingles: Ce n'est pas vrai du tout. Boost :: Lier Code> Est-ce que c'est fait. Soit vous utilisez
boost :: lid code> ou vous roulez votre propre
boost :: lid code>, mais à la fin de la journée, c'est toujours
boost :: lié < / Code> Sous quel que soit le nom que vous le donnez.
Puisque personne n'a déjà publié le code de boost réel, C ++ 98 avec boost: test de test https://ideone.com/pavje p> comme pour pure C ++, je ne pense pas qu'il soit possible sans le Et ici, c'est (à l'aide de la mise en œuvre de GCC de stl) p> essai de test: https://ideone.com/eqbs5 p> modifier: corrigé pour tenir compte de compose1 code> adaptateur, présent dans STL mais pas en C ++ stdlib ... p>
personne * code> p> p>
Petite différence, l'OP utilise std :: vecteur
personne * code> avant d'appliquer la fonction membre, et il est possible que c'est null (dans le cas général).
@Matthieu M Fait: S / MEM_FUN_REF / MEM_FUN / CODE> M Bien que la possibilité de la désérofacturation du pointeur NULL sera certainement présente avec la plupart des solutions à une doublure. C'est-à-dire que cela peut être pris en charge, mais la solution deviendrait illisible.
@Matthieu - Le fait que le vecteur contient personne * code> fait une différence (autre que le numéro de pointeur NULL mentionné ci-dessus)? Le seul changement que je peux voir est que vous devez utiliser MEM_FUN au lieu de MEM_FUN_RF, ce qui réduit efficacement la différence entre. * Et -> * *
@RODION: J'espère que non: P Je pense que boost :: lid code> s'écoute automatiquement avec elle.
Pas une réponse: j'aime les techniques fonctionnelles, mais j'ai abandonné sur des algorithmes stl-algorithmes pour des objets. Lambda est vraiment le lien manquant de C ++ 03. Même avec Boost.Lambda, il y a beaucoup de bizarreries. Les sl-algorithmes fonctionnent bien avec les primitives, mais j'utilise rarement des conteneurs de primitives ... cela va-t-il d'éviter les boucles lorsqu'elles sont remplacées par des constructions liées?
Est-il normal que
getname () code> reviendrait par copie?
Boost :: Bind est beaucoup plus propre que STD :: Binday cependant, et vous pouvez combiner Boost Lambdas dans.
@stefaanv - Je pense que dans des conditions pratiques, je serais d'accord la plupart du temps. Si un exemple, ce simple est arrivé, je voudrais probablement écrire la boucle. @Matthieu - Je comprends d'où vous venez d'où vous venez, mais l'exemple est intégré à cet objectif de cette question et de revenir par copie vs retour de Cons Ref n'est pas quelque chose que j'ai vraiment pensé (je ne pense pas que cela change le cadrage de la question).
@Rodion Ingles: Pas du tout, autant que je sache, la création du temporaire compliquera légèrement le travail du compilateur mais ne devrait pas avoir une incidence sur la correction des solutions présentées.
J'essaie (et échoué) de trouver une solution à ce que vous demandez. J'espère que quelqu'un a plus de succès que moi, sinon quelqu'un pouvait expliquer pourquoi cela ne peut pas être fait.
@Captain girafe Vous ne pouviez pas faire cela car C ++ 98 n'incluait pas la partie requise de STL, voir Stackoverflow.com/questions/5325122/...