Bonjour à tous (ça fait un bail que je passais plus par ici)
Voici un petit code sympa de foncteur générique simple.
Et voici un petit code exemple d'utilisation (je vous laisse ajouter les #include nécessaires si vous l'essayer).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 template<class C, typename T, T C::*P> struct by_member { bool operator()(C const & rl, C const & rr) const { return rl.*P < rr.*P; } bool operator()(C const & rl, T const & t) const { return rl.*P < t; } bool operator()(T const & t, C const & rr) const { return t < rr.*P; } };
Simple, propre et efficace me semble-t-il.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 struct employee { int f_id; std::string f_firstname; std::string f_lastname; int f_ssnumber; employee(int id, std::string const & firstname, std::string const & lastname, int ssnumber) : f_id(id), f_firstname(firstname), f_lastname(lastname), f_ssnumber(ssnumber) {} }; typedef by_member<employee, std::string, &employee::f_lastname> by_lastname; int _tmain(int argc, _TCHAR* argv[]) { std::vector<employee> v; v.push_back(employee(5, "John", "Smith", 1582)); v.push_back(employee(3, "Paul", "Howard", 1777)); v.push_back(employee(7, "Jude", "Muller", 1325)); std::sort(v.begin(), v.end(), by_lastname()); if ( std::binary_search(v.begin(), v.end(), "Muller", by_lastname()) ) std::cout << "Found" << std::endl; return 0; }
Maintenant je souhaiterais un foncteur utilisant deux membres de employee (ou plus) afin de former une clé multiple permettant de trier puis rechercher sur, par exemple, f_lastname et f_firstname.
Je pensais adapter by_member<> comme ceci (c'est juste un début de réflexion):
Pour un usage comme ceci par exemple:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 template<class C, typename T1, T1 C::*P1, typename T2, T2 C::*P2> struct by_2_members { bool operator()(C const & rl, C const & rr) const { return rl.*P1 < rr.*P1 || (rl.*P1 == rr.*P1 && rl.*P2 < rr.*P2); } bool operator()(C const & rl, Tuple? const & t) const { // ici ça coince... return rl.*P1 < t<1> || (rl.*P1 == t<1> && rl.*P2 < t<2>); } bool operator()(Tuple? const & t, C const & rr) const { // et ici aussi... return t<1> < rr.*P1 || (t<1> == rr.*P1 && t<2> < rr.*P2); } };
Je n'aime que moyennement utiliser std::tuple<>, toute idée pour l'éviter est bienvenue.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 typedef by_2_members<employee, std::string, &employee::f_lastname, std::string, &employee::f_firstname> by_lastname_firstname; ... std::sort(v.begin(), v.end(), by_lastname_firstname()); if ( std::binary_search(v.begin(), v.end(), std::tuple("Muller", "Jude"), by_lastname_firstname()) ) std::cout << "Found" << std::endl;
Ensuite l'usage d'un variadic template pour écrire une forme générale de by_member<> serait pas mal aussi (sans tout transformer en usine à gaz).
Merci pour vos avis![]()
Partager