8
votes

Comment STD :: Recherche à l'aide d'un objet Comparer?

Je suis confus sur l'interface de std :: Trouver code>. Pourquoi ne prend-il pas un objet code> comparer code> qui lui indique comment comparer deux objets?

Si je pouvais passer un Comparer l'objet code> Je pourrais faire fonctionner le code suivant, où j'aimerais comparer par la valeur, au lieu de simplement comparer les valeurs du pointeur directement: P>

template<class T>
struct MyEqualsByVal {
  const T& x_;
  MyEqualsByVal(const T& x) : x_(x) {}
  bool operator()(const T& y) const {
    return *x_ == *y;
  }
};
// ...
vec.push_back(s1);
Vec::const_iterator found = 
    std::find_if(vec.begin(), vec.end(),
                 MyEqualsByVal<std::string*>(s2)); // OK, will find "foo"


0 commentaires

3 Réponses :


2
votes

Etant donné que votre t est un pointeur, vous pouvez également stocker une copie du pointeur dans l'objet de fonction.

Autre que cela, c'est comme ça que c'est fait et il n'y a pas beaucoup de plus à cela.

En côté, ce n'est pas une bonne idée de stocker des pointeurs nus dans un conteneur, à moins que vous ne soiez extrêmement prudent pour assurer la sécurité des exceptions, qui est presque toujours plus tracieuse qu'on vaut la peine.


1 commentaires

Et ... j'ai totalement manqué la première moitié de la question ... Oups. Cependant, la réponse de Steve Jessop est meilleure que celle que je pouvais l'avoir expliqué quand même.



0
votes

C'est exactement ce que wind_if est pour - il faut un prédicat appelé à comparer des éléments.


0 commentaires

7
votes

trouver ne peut pas être surchargé pour prendre un prédicat unitaire au lieu d'une valeur, car c'est un paramètre de modèle non contraint. Donc, si vous appelez trouver (premier, dernier, my_predicate) , il y aurait une ambiguïté potentielle si vous souhaitez que le prédicat soit évalué sur chaque membre de la gamme, ou si vous souhaitez trouver un membre de La gamme qui est égale au prédicat lui-même (il pourrait s'agir d'une gamme de prédicats, pour tous les concepteurs des bibliothèques standard, sachez ou soin, ou le valse_type de l'itérateur pourrait être convertible à la fois sur le type de prédicat. , et à son argument_type ). D'où le besoin de wind_if passer sous un nom distinct.

trouver aurait pu être surchargé pour prendre un prédicat binaire facultatif, en plus de la valeur recherchée. Mais capturer des valeurs dans les fonctions, comme vous l'avez fait, est une technique si standard que je ne pense pas que ce serait un gain massif: il n'est certainement jamais nécessaire car vous pouvez toujours obtenir le même résultat avec Find_if .

Si vous avez eu le rechercher que vous vouliez, vous devez toujours écrire un foncteur (ou utiliser Boost), car ne contient rien à Déroférence Un pointeur. Votre foncteur serait un peu plus simple en tant que prédicat binaire, ou vous pouvez utiliser un pointeur de fonction, ce serait donc un gain modeste. Donc, je ne sais pas pourquoi cela n'est pas fourni. Compte tenu du copy_if fiasco Je ne suis pas sûr qu'il y a beaucoup de valeur en supposant qu'il y a toujours de bonnes raisons pour les algorithmes qui ne sont pas disponibles: -)


1 commentaires

@Dehmann: La seule chose qui ne va pas avec c'est que ce n'est pas dans la norme. Il a été laissé de côté essentiellement en raison d'un accident d'édition.