Question

Juste curieux de savoir pourquoi la fonction de comparaison de stl :: sort ne peut pas être un membre statique?

J'ai une petite petite classe d'assistance foo déclarée et définie dans un en-tête, mais je dois maintenant créer un fichier foo.cpp pour l'implémentation de cmp () afin qu'il ne soit pas défini de manière multiple.

Je dois aussi penser à un nom bien décoré pour que fooCmp () ne se heurte à aucun autre cmp ().

Parce qu’elle n’a accès à aucune variable membre, aucune opération de comparaison nécessitant l’accès à une autre valeur (par exemple, trier par distance de foo.bar) nécessite l’appel complexe bind2nd.

Était-ce utile?

La solution

Je ne suis pas sûr de ce dont vous vous plaignez:

std::sort(begin,end)        // use operator<
std::sort(begin,end,order)  // Where order is a functor

Donc, l'ordre peut être:

  • Une fonction
  • Une fonction membre statique
  • Ou un objet qui se comporte comme une fonction.

Ce qui suit fonctionne pour moi:

class X
{
    public: static bool diff(X const& lhs,X const& rhs) { return true;}
};

int main()
{
    std::vector<X>   a;

    std::sort(a.begin(),a.end(),&X::diff);
}

Mais si la classe a un ordre naturel, pourquoi ne pas simplement définir l'opérateur < pour la classe. Cela vous permettra d'accéder aux membres et se comportera bien pour la plupart des conteneurs / algorithmes standard qui doivent définir un ordre.

class X
{
    public: bool operator<(X const& rhs) const   {  return true;}
};
int main()
{
    std::vector<X>   a;

    std::sort(a.begin(),a.end());
}

Autres conseils

Si une fonction de comparaison définie par plusieurs éléments vous intéresse, essayez de la déclarer avec une liaison static. Ensuite, la portée de la fonction ne s'étend pas au-delà de l'unité de compilation où elle se trouve.

Cela dit, votre fonction de comparaison & "; fonction &"; ne doit pas nécessairement être une fonction, mais peut être une fonction objet . Un objet fonction ressemble beaucoup à une fonction, mais il est implémenté comme un operator() qui prend les paramètres appropriés dans une classe normale. Comme il s’agit d’une classe normale, vous pouvez lui transmettre les paramètres du constructeur.

Voici un exemple simple:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class comparator {
public:
    bool operator()(int a, int b) {
        return a < b;
    }
};

int main(int, char *[])
{
    vector<int> a;
    a.push_back(1);
    a.push_back(3);
    a.push_back(2);
    sort(a.begin(), a.end(), comparator());
    cout << a << endl;
}

ressemble réellement à la fonction déclaré dans la classe, défini dans l'en-tête mais en dehors de la classe sans liaison inline

c'est-à-dire quelque chose comme:

class foo{
public:
   static bool compare(const foo& lhs,const foo& rhs);
   ...
};
bool foo::compare(const foo& lhs,const foo& rhs){
   ...
} 

au lieu de

class foo{
public:
   static bool compare(const foo& lhs,const foo& rhs);
   ...
};
inline bool foo::compare(const foo& lhs,const foo& rhs){
   ...
} 

le premier provoquera la définition de la fonction dans chaque unité de compilation qui

#includes "foo.h"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top