J'essaie de changer l'ordre par défaut des éléments dans un ensemble d'entiers pour qu'ils soient lexicographiques au lieu de numériques, et je ne parviens pas à compiler les éléments suivants avec g ++:
file.cpp:
bool lex_compare(const int64_t &a, const int64_t &b)
{
stringstream s1,s2;
s1 << a;
s2 << b;
return s1.str() < s2.str();
}
void foo()
{
set<int64_t, lex_compare> s;
s.insert(1);
...
}
J'obtiens l'erreur suivante:
error: type/value mismatch at argument 2 in template parameter list for ‘template<class _Key, class _Compare, class _Alloc> class std::set’
error: expected a type, got ‘lex_compare’
Qu'est-ce que je fais mal?
std::set<int64_t, decltype(&lex_compare)> s(&lex_compare)
1. Solution C ++ 20 moderne
Nous utilisons la fonction lambda comme comparateur. Comme d'habitude, le comparateur doit retourner une valeur booléenne, indiquant si l'élément passé en tant que premier argument est considéré comme précédant le second dans l'ordre strict strict qu'il définit.
Démo en ligne
2. Solution C ++ 11 moderne
Avant C ++ 20, nous devons passer lambda comme argument pour définir le constructeur
Démo en ligne
3. Similaire à la première solution, mais avec fonction au lieu de lambda
Rendre le comparateur comme une fonction booléenne habituelle
Ensuite, utilisez-le, soit de cette façon:
Démo en ligne
ou de cette façon:
Démo en ligne
4. Ancienne solution utilisant struct avec
()
opérateurDémo en ligne
5. Solution alternative: créer une structure à partir d'une fonction booléenne
Prendre la fonction booléenne
Et en faire une structure en utilisant
std::integral_constant
Enfin, utilisez la structure comme comparateur
Démo en ligne
la source
La réponse de Yacoby m'inspire pour écrire un adaptateur pour encapsuler le passe-partout du foncteur.
Wow, je pense que ça valait la peine!
la source
Vous pouvez utiliser un comparateur de fonctions sans l'envelopper comme suit:
ce qui est irritant à taper à chaque fois que vous avez besoin d'un ensemble de ce type, et peut causer des problèmes si vous ne créez pas tous les ensembles avec le même comparateur.
la source
std::less<>
lors de l'utilisation de classes personnalisées avecoperator<
Si vous avez affaire à un ensemble de votre classe personnalisée qui a été
operator<
définie, vous pouvez simplement utiliserstd::less<>
.Comme mentionné sur http://en.cppreference.com/w/cpp/container/set/find C ++ 14 a ajouté deux nouvelles
find
API:qui vous permettent de faire:
main.cpp
Compilez et exécutez:
Vous
std::less<>
trouverez plus d'informations sur : Que sont les comparateurs transparents?Testé sur Ubuntu 16.10,
g++
6.2.0.la source