Salut à tous

Bon, pas d’inquiétude avec mon titre trollesque, j'attaque pas le C++11.

Je discutais avec germinolegrand sur le chat suite à ce bout de code qu'il me présente :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
std::list<std::pair<sf::Vector2f, sf::ConvexShape>> m_triangles;
auto it = std::find_if(begin(m_triangles), end(m_triangles), [pos](const std::pair<sf::Vector2f, sf::ConvexShape> &p){return p.first == pos;});
Jusque là, rien à dire, utilisation classique des lambdas...

En bien si, je critique (comme d'habitude )

On comprend que l'on a une liste de triangles avec le nom de la variable, mais les triangles, ce sont std::pair<sf::Vector2f, sf::ConvexShape> ou sf::ConvexShape ? A quoi correspond sf::Vector2f ? Ok, on fait un find pour trouver le triangle qui à un sf::Vector2f donné, mais ça correspond à quoi ? Trouver les triangles qui ont un point commun ? Le même centre ?

Avec les facilités d'écriture du C++11, ne risque-t-on pas de voir une utilisation à outrance, quitte à perdre de la sémantique ?

Sur l'exemple de code précédent, j'aurais plus vu l'utilisation d'une classe (je simplifie le code un peu, en particulier au niveau des accès) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
struct Triangle {
    sf::Vector2f center;
    sf::ConvexShape points;
    bool operator== (Triangle const& t) const { return t.center == center; }
};
 
auto it = std::find(begin(m_triangles), end(m_triangles), pos);
Dans l'idée qu'une classe est un contrat entre le dev d'une classe et les utilisateurs de cette classe, créer un tel objet permet de :
1. définir correctement un sémantique sur Triangle (de valeur ici), c'est à dire comment doit être compris cette classe, ce quelle représente et donc que l'on peut faire (ou pas) avec cette classe
2. de contrôler les accès aux variables membres (rien n'interdit dans le code avec pair de modifier le centre d'un triangle, ce qui n'aurait pas de sens)
3. que le lecteur sache à quoi correspond les variables qu'il manipule. sf::Vector2f peut être un angle, le barycentre, le centre des cercles conscrit ou circonscrits, etc.

Idem pour le find. On peut le laisser tel quel dans le code. Ou on peut aussi l'encapsuler dans une fonction pour lui donner un sens :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
template<class TRIANGLE>
auto findCorrespondingTriangle(typename TRIANGLE::CenterType const& pos, list<TRIANGLE> const& triangles) {
    return std::find(begin(triangles), end(triangles), pos);
}
(bon, c'est l'idée. Pour mieux faire, on peut également ajouter une abstraction pour le type de conteneur et proposer une politique pour le type de correspondance que l'on recherche : triangles avec centre en commun, triangles sécants, etc)


Bon, sur 2 lignes de code, c'est un peu caricatural. Mais j'ai l'impression que l'on voit de plus en plus ce genre de code, où l'auteur pense (à tort à mon avis, si c'est pour économiser 2 lignes) que plus c'est court, mieux c'est.
Vous en pensez quoi ?