2009-04-05 11 views
7

Cette question est une question de style, car vous pouvez toujours écrire une boucle for ou quelque chose de similaire; cependant, existe-t-il un STL ou un BOOST moins gênant pour l'écriture:Appelez la fonction membre sur chaque élément d'un conteneur

for (container<type>::iterator iter = cointainer.begin(); 
    iter != cointainer.end(); 
    iter++) 
iter->func(); 

?

Quelque chose comme (imaginé) ceci:

call_for_each(container.begin(), container.end(), &Type::func); 

Je pense que ce serait 1) moins de frappe, 2) plus facile à lire, 3) moins de changements si vous décidez de changer le type de base/type de conteneur.

EDIT: Merci pour votre aide, maintenant, et si je voulais passer certains arguments à la fonction membre?

Répondre

4

J'ai découvert que bind boost semble être bien adapté à la tâche, plus vous pouvez transmettre des arguments supplémentaires à la méthode:

#include <iostream> 
#include <functional> 
#include <boost/bind.hpp> 
#include <vector> 
#include <algorithm> 

struct Foo { 
    Foo(int value) : value_(value) { 
    } 

    void func(int value) { 
     std::cout << "member = " << value_ << " argument = " << value << std::endl; 
    } 

private: 
    int value_; 
}; 

int main() { 
    std::vector<Foo> foo_vector; 

    for (int i = 0; i < 5; i++) 
     foo_vector.push_back(Foo(i)); 

    std::for_each(foo_vector.begin(), foo_vector.end(), 
     boost::bind(&Foo::func, _1, 1)); 
} 
+0

+1 parce que vous me battez par 5 minutes avec cette réponse de liaison: p (oh, std :: mem_fun_ref est de la merde en utilisant des arguments liés!) –

+0

+1, pour comprendre cela sans tout par vous-même et pour utiliser Boost. À votre santé! – dirkgently

+0

ce que je veux dire est quand vous avez référence à des références lorsque vous avez la fonction membre a un paramètre de référence. boost :: bind résout si bien :) –

22
#include <algorithm> // for_each 
#include <functional> // bind 

// ... 

std::for_each(container.begin(), container.end(), 
        std::bind(&Type::func)); 

Voir std::for_each et std::bind documentation pour plus de détails.

Vous avez manqué votre edit: Anyway ici une autre façon de réaliser ce que vous voulez sans utiliser Boost, si jamais besoin d'être:

std::for_each(foo_vector.begin(), foo_vector.end(), 
    std::bind(&Foo::func, std::placeholders::_1)); 
+0

me battra 8 secondes – JaredPar

+0

@ JaredPar/bb : ROFLMAO! – dirkgently

+0

mes 2 cents pour votre vitesse :) –

5

Vous pouvez utiliser std::for_each ou boost's foreach constructs. Utilisez BOOST_FOREACH ou BOOST_REVERSE_FOREACH boost lorsque vous ne voulez pas déplacer la logique dans une autre fonction.

+1

+1. BOOST_FOREACH (type & t, conteneur) t.func(); ça a l'air assez sympa –

0

Si vous voulez vraiment améliorer les performances plutôt que simplement améliorer votre code, vous avez vraiment besoin d'une fonction de carte. Eric Sink a écrit un .net implementation

+0

Merci, je suis à la recherche d'une solution générique C++ (indépendante de la plate-forme). – kyku