La spécification du C++17 n'intègrera pas les concepts
Comprenez pourquoi la fonctionnalité a été retardée

Le , par LittleWhite

0PARTAGES

8  2 
La nouvelle spécification du C++, nommée C++17 approche à grands pas. Toutefois, la fonctionnalité des concepts n'intègrera pas la future spécification. Tom Honermann explique sur son blog les raisons faisant que c'était improbable, voire impossible.
Toutefois, avant de décrire ces raisons, rappelons ce que sont les concepts.

Prenons le concept suivant :
Code c++ : Sélectionner tout
1
2
3
auto concept LessThanComparable<typename T> { 
    bool operator<(T, T); 
}
Celui-ci indique que n’importe quel type ayant un operator< et qui prend en paramètre deux objets et retournant un booléen sera considéré comme un LessThanComparable. Ensuite, il est possible d’utiliser le concept pour restreindre les types pouvant être passés à un template.

Le but des concepts est d'apporter une solution à un manque du C++. En effet, même s'il est possible de contourner le manque, il est impossible d'apporter une solution propre. Grâce aux concepts il devient possible :
  • de contraindre les arguments d'une fonction sans pour autant désactiver la déduction de ceux-ci et sans gêner la meta arity des fonctions templates ainsi contraintes. Prenons l’exemple suivant :
    Code c++ : Sélectionner tout
    template <class T> void f(T);
    L’exemple est plutôt simple. Toutefois, nous aimerions ajouter une interface. Pour ce faire, nous voudrions contraindre les paramètres de la fonction :
    Code c++ : Sélectionner tout
    template <class T> void f(enable_if_t<my_trait_v<T>, T>);
    Mais ce faisant, nous avons perdu la déduction des arguments. Aussi, cela ne fonctionnera pas pour les constructeurs templates. Une seconde approche serait :
    Code c++ : Sélectionner tout
    template <class T> auto f(T) -> enable_if_t<my_trait_v<T>, void>;
    La contrainte du paramètre se situe dans le type de retour. Toutefois, cela ne marche toujours pas pour les constructeurs templates. Ce que nous pouvons corriger en ajoutant une contrainte sur l’argument template :
    Code c++ : Sélectionner tout
    template <class T, typename = enable_if_t<my_trait_v<T>>> void f(T);
    Malheureusement, la meta arity est passée de 1 à 2. De plus, ce n’était que des contournements alors qu’avec les concepts nous pourrions faire :
    Code c++ : Sélectionner tout
    void f(MyConcept);
  • d’écrire plus facilement des surcharges tout en ayant des contraintes exclusives mutuellement. Il est souvent souhaité de pouvoir utiliser telle ou telle surcharge suivant certaines conditions sur les templates. Pour réussir, on pourrait écrire :
    Code c++ : Sélectionner tout
    template <class T> void f(T, decltype(declval<T>().f())* = 0);
    Ce code est dangereux. On peut facilement en arriver à ce point si on ne souhaite pas créer de trait (car c’est l’unique utilisation). De plus, les références ne sont pas gérées, la contrainte peut être ignorée en passant deux arguments à la fonction. Avec les concepts, nous pourrions écrire :
    Code c++ : Sélectionner tout
    1
    2
    template <class T> void f(T) requires requires (T t) {t.f();}; 
          template <class T> void f(T);
    Les surcharges sont mutuellement exclusives.
  • d’écrire des contraintes aussi originales que nécessaires.


Malgré tout l’intérêt que peuvent avoir les concepts, ceux-ci n'intégreront pas le prochain standard. En effet, plusieurs choses ne sont pas encore claires :
  • la spécification des concepts a été publiée le 15 novembre 2015, laissant peu de temps pour un retour efficace et fiable ;
  • la seule implémentation est dans une version non publiée de GCC ;
  • l’implémentation réalisée dans GCC a été réalisée par l’auteur de la spécification. Il n’y a donc pas eu d’avis externe sur la question de l’implémentation dans GCC ou dans les autres compilateurs ;
  • seuls quelques projets utilisent les concepts, mais la spécification n’a pas été assez mise à l’épreuve dans des cas réels ;
  • la spécification ne fournit pas de bibliothèque de définitions de concepts. Donc il n’est pas possible de savoir si l’écriture d’une telle bibliothèque est possible.


Toutefois, même si tous ces points avaient été réglés, Tom Honermann doute de l’intégration des concepts à la spécification du langage. En effet :
  • les concepts apportent une nouvelle écriture pour les templates. Toutefois, une fonction template abrégée peut être identique à une fonction non template. Le type serait le seul indicateur pour savoir si la fonction est non template ou si elle est template :
    Code c++ : Sélectionner tout
    void f(X x) {}
  • la proposition définit une nouvelle syntaxe pour déclarer des templates respectant une contrainte :
    Code c++ : Sélectionner tout
    C{A,B} void f(A a, B b);
    toutefois, cette syntaxe n’est pas appréciée ;
  • l’utilisation d’un concept nécessite de connaître comment il a été défini (fonction ou variable). Cela apporte confusion et est source d’erreurs ;
  • les concepts sont attendus pour améliorer les messages d’erreur. Toutefois, l’utilisation erronée des concepts peut apporter des erreurs encore plus denses qu’à l’accoutumée liées à la surcharge des fonctions ;
  • de nombreuses autres questions ont été soulevées et ne pourront être répondues qu’à travers des tentatives d’utilisation.


Même si ce constat est malheureux pour tout utilisateur du langage souhaitant les concepts au plus tôt, ces derniers devraient arriver dans la prochaine spécification. De plus, il y a de grandes chances pour que chaque compilateur propose une implémentation bien avant la complétion du futur standard. Finalement, ce retard permet d’affiner l’implémentation et ainsi, au comité de proposer une meilleure fonctionnalité.

Votre opinion

Aviez-vous déjà imaginé des cas d’utilisation pour les concepts ? Quels sont-ils ?
Quelles autres fonctionnalités du C++ attendez-vous ?

Source

Blog de Tom Honermann
IsoCPP

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de JolyLoic
Rédacteur/Modérateur https://www.developpez.com
Le 19/04/2016 à 23:17
Je suis assez en désaccord avec ce post qui présente pour moi une vue biaisée de la situation. Même si je n'étais pas à la dernière réunion, j'ai suivi d'assez près son contenu.

la spécification des Concepts a été publiée le 15 novembre 2015, laissant peu de temps pour un retour efficace et fiable
La spécification des concepts existe depuis longtemps... C'est le fait que cette spécification soit sous forme de TS qui est récent. Même si le design a commencé bien avant, la première spécification existe depuis janvier 2014. Elle a évolué, certes, mais si on va par là, toutes les propositions évoluent, c'est leur objectif, et si on imposait à toute évolution une période de non évolution de plusieurs années avant d'être acceptées, on n'aurait rien dans C++17.

la seule implémentation est dans une version non publiée de GCC ;
Version qui ne pouvait pas être publiée, puisque les concepts ne sont pas dans le langage.... C'est l’œuf et la poule... Et c'était l'intérêt du TS que de rassurer les fabricants de compilateurs à faire l'effort d'implémentation avant la standardisation. Et il faut savori que de nombreuses fonctionnalités du langage ne sont que dans des versions non publiées avant d'être acceptées (certaines ne sont même pas implémentées dans leur forme finale...).

l’implémentation réalisée dans GCC a été réalisée par l’auteur de la spécification. Il n’y a donc pas eu d’avis externe sur la question de l’implémentation dans GCC ou dans les autres compilateurs ;
C'est le cas pour l'immense majorité des nouvelles fonctionnalités du langage. Et je n'ai jamais entendu cet argument utilisé pour autre chose que les concepts... Pour les autres cas, une question est récurrente est "Est-ce que ça a été implémenté?". Pour les concepts, il semblerait que la question soit "Est-ce que ca a été implémenté 3 fois par 3 équipes différentes dont aucune n'a le droit de contenir l'auteur principal de la proposition?"...

seuls quelques projets utilisent les concepts, mais la spécification n’a pas été assez mise à l’épreuve dans des cas réels ;
Et comment pourrait-elle l'être plus, tant que la proposition n'est pas acceptée ? Elle a été utilisée dans divers contextes, le contexte manquant le plus gênant étant la STL. Mais des grandes bibliothèques l'ont utilisée (range, par exemple)

la spécification ne fournit pas de bibliothèque de définitions de concepts. Donc il n’est pas possible de savoir si l’écriture d’une telle bibliothèque est possible.
C'est un point gênant mais hélas classique. Les gens qui travaillent sur le langage et ceux qui travaillent sur la bibliothèque sont différents, et tant qu'une fonctionnalité n'a pas été acceptée dans la langage, implémentée dans plusiuers compilateurs, les bibliothèques ont du mal à suivre. Par exemple, plusieurs années après la mise en place de noexcept, on ne savait toujours pas sur quelles fonctions de la bibliothèque mettre noexcept ou pas. Même chose pour constexpr qui est seulement en train d'être ajouté à la bibliothèque standard.

les Concepts apportent une nouvelle écriture pour les templates. Toutefois, une fonction template abrégée peut être identique à une fonction non template. Le type serait le seul indicateur pour savoir si la fonction est non template ou si elle est template :
C'est le cas depuis le début, ça a été discuté et accepté. Après, certains n’aiment pas, mais à part rouvrir sans cesse les vieux débats...
Il est courant en C++ de ne pas pouvoir dire ce qu'est un code sans connaître le contexte. Si je dis
Code : Sélectionner tout
1
2
void f(double d) {};
f(2);
Je ne peux pas dire si cette fonction f sera appelée sans savoir s'il n'y a pas aussi visible dans le scope une autre fonction qui serait préférée. C'est la base de la surcharge, et ça ne gêne personne.
Et bien, dans le même ordre d'idée, si je vois void f(Container const &c), je ne peux pas savoir sans un peu de contexte si je définis une fonction ou un template, mais :
- Généralement, je connais le contexte, et je peux dire par exemple que Container est un concept, et donc que je définis un template, mais que f(vector<int> const &v) va définir une fonction.
- Le nom lui même doit m'aider
- Et la plupart du temps, je m'en moque totalement de savoir si une fonction est un template ou pas. J'ai sous la main en conteneur (sans savoir forcément son type exact, il est peut-être dans une variable auto initialisée par un retour de fonction, ou dans un argument template), je peux appeler f, c'est tout ce qui compte.

les Concepts sont attendus pour améliorer les messages d’erreur. Toutefois, l’utilisation erronée des Concepts peut apporter des erreurs encore plus dense qu’à l’accoutumée lié à la surcharge des fonctions ;
Je manque de recul sur ce point (toujours pareil, tant qu'on ne l'a pas vraiment dans un compilo qu'on utilise quotidiennement...), mais :
- Ce n'est pas le cas le plus courant
- Lire une longue liste de surcharge reste au niveau sémantique de l'interface. Pour les gens ayant l'habitude de plonger dans l'implémentation, peut-être que c'est un peu plus long, mais pour les gens voulant rester au niveau de l'interface, c'est mieux !
- Je ne doute pas qu'avec le temps, les compilateurs pourront affiner les messages d'erreur liés aux concepts (par exemple, lister en premier parmi les surcharges celle qui était le plus proche de passer, et donc la plus susceptible d'être la bonne).

de nombreuses autres questions ont été soulevées et ne pourront être répondues qu’à travers des tentatives d’utilisations.
Et ces tentatives ne pourront avoir lieu que quand les compilateurs proposeront cette fonctionnalité. Et qu'ils la proposeront vraiment, pas avec un flag "expérimental" et d'autres joyeusetés qui empêcheraient les gens de l'utiliser dans un vrai contexte professionnel. J'espère vraiment que la présence du TS ira dans cette direction... Je ne doute pas qu'il y aura des petits problèmes avec les concepts... Il y en a eu avec toutes les grosses fonctionnalités du langage. La move sémantic était totalement bancale bien après qu'elle ait été mise dans la langage, les lambda étaient incomplets...

Le problème, c'est qu'il y a un risque à ne pas livrer les concepts qui est pour moi plus important que le risque actuel de livrer des concepts imparfaits. Pour une autre vision sur le sujet, je vous propose de lire http://www.open-std.org/jtc1/sc22/wg...6/p0225r0.html
8  0 
Avatar de bacelar
Expert éminent sénior https://www.developpez.com
Le 20/04/2016 à 14:41
Citation Envoyé par Aiekick Voir le message
personnellement j'ai toujours regretté d’avoir appris le c++ comme 1er langage avant le c.
Pour avoir subit l'inverse, je peux te garantir que C puis C++ c'est la combo maudite pour faire de la merde sans le savoir.

Arrêtez de pendre vos lunettes de vieux cons, comment pouvez-vous regretter l'utilisation systématique de pointeurs nus dans un langage à exception ?
Les smart pointeurs, c'est irremplaçable, jusqu'à trouver encore mieux.

La normalisation du C++ a une démarche proche des framework progressifs, rendre simple les cas courants, faire en sorte que les cas courants couvre le plus de cas possible et faire en sorte que les cas rares et complexes soient
Et oui, la programmation générique (template simple), le code fonctionnel à base de lambda, la programmation parallèle ou concurrente sont des cas maintenant des plus courants ou en passe de l'être. Et que les normalisateurs me tracent une autoroute pour m'en servir le plus simplement du monde, je leur en suis profondément reconnaissant.

Moi, je ne maitrise pas le C++, même après plus de 20ans d'utilisation, mais tant que j'arrive à faire ce que je veux et qu'en cherchant un peu je trouve de super trucs qui me simplifient la vie, bibliothèque ou nouvelles normes, je suis content.

Avoir l'illusion de maitriser un machin et bien plus dévastatrice que de savoir qu'on ne sait rien.

Désolé les gars, mais les seules personnes qui peuvent dire que le C++ est trop compliqué, c'est les vrais débutants, pas ceux qui se paluchent les intrinsics des compilateurs en assembleur x64 ou Itanium.
6  0 
Avatar de Luc Hermitte
Expert éminent sénior https://www.developpez.com
Le 21/04/2016 à 10:08
A propos de C plus léger et plus rapide, je renvoie aux présentations que j'avais évoquées ici: http://www.developpez.net/forums/d32...r/#post8505022

Sinon, AMA, trouver ce type de code plus simple à comprendre est une illusion dont on se berce.
Ceci n'est que le code "bas-niveau". Comme je disais, imaginez maintenant un filtre qui va extraire un bandeau de l'image (et donc construire un objet sous-image), et parser tous les pixels pour calculer des statistiques ou faire autre chose.
Il faut prévoir une nouvelle ressource allouée : le bandeau (et donc sa libération en cas d'erreur sur get_pixel), et une boucle qui va itérer sur chaque pixel. Ce cas est encore simple. Cela devient encore plus compliqué sur des calculs de corrélation où l'on extrait 2 bandeaux qui sont parcourus simultanément).
Déjà qu'un code C correct est complexe: cf le code en bas à gauche dans http://alexandre-laurent.developpez....ou-exceptions/, si en plus on rajoute de la programmation défensive (pour résister aux erreurs de programmation), le code devient encore plus complexe.

En C, il aurait été plus propre de rendre la classe/structure image complètement cachée (comme FILE), histoire de retirer le code qui vérifie à chaque fois si tout ce qui est reçu est dans un état correct. C'est à dire: simuler des invariants assurés par encapsulation+constructeur.

Mon point, est que le C++ offre de "nouveaux" (pour le coup, ceux là vieux) moyen pour simplifier notre code. On ne va quand même pas refuser des sucres syntaxiques sous prétexte que c'est une syntaxe alternative à une que nous avons déjà.
5  0 
Avatar de Luc Hermitte
Expert éminent sénior https://www.developpez.com
Le 21/04/2016 à 12:56
Citation Envoyé par RPGamer Voir le message
Les mécanismes de C++ sont à la fois plus complexes et plus lourds, c'est donc logique. Les cas présentés à charge du C sont sélectionnés et hors contexte. Dans la majorité des cas, les performances de C sont meilleures comme le montre ce benckmark. La plupart des lib bas niveau et des applications temps-réel sont écrites en C en partie pour cette raison. N'importe quel ingénieur sérieux dans l'embarqué le dira. J'aime beaucoup C++ mais il n'est pas à même de tenir la barre dans les applications critiques ou nécessitant des performances.
Si tu prends fasta, et regarde les codes, tu verras une énorme différence: "#pragma OMP". On ne compare pas les mêmes choses. Pour les arbres binaires, on n'utilise pas le même COTS. Pareil pour la lib de regex dans le suivant. Il est difficile de comparer quand autant d'éléments changent, et qu'il ne s'agit pas juste de remplacer des structures par des classes (pour mieux contrôler les invariants et remplacer de nombreux cas d'utilisation du débuggeur par le compilateur dans l'assistance à la maintenance de l'application), et prendre un peu de template par-ci par-là.

La part du C dans l'embarqué est du à deux raisons : la tradition et les aprioris (je ne sais plus si c'est le sujet de la 1ère ou de la 2nd présentation de Dan Saks lors du dernier code::dive), et au problème de support par des compilateurs maintenus par les fournisseurs de matos (qui n'ont pas forcément envie, ni les moyens, de fournir des compilateurs plus complexes comprenant le C++). Et aussi on a facilement des problèmes d'ABI. Si tu veux faire dans l'ad hominem, je pense pouvoir dire que Dan Saks est un développeur sérieux qui bosse dans l'embarqué. Et pourtant il se fait l'avocat du C++ depuis très longtemps.

Qui plus est, si une construction propre au C++ n'est pas acceptable, il suffit d'utiliser l'équivalente du C. Un code C compilé avec un compilateur C++ n'a pas à être plus lent -- cf la video de l'autre intervenant dont le nom m'échappe. A partir de là, tu utilises juste ce que tu veux du C++. Et même en embarqué (moyennant la disponibilité d'un compilateur), tu ne dois pas observer de dégradations.

Citation Envoyé par yahiko Voir le message
Je pense qu'il y a un souci dans la façon dont tu t'exprimes.
Le fait que du code soit simple a comprendre n'implique pas qu'il soit approprié pour une situation donnée.
Tu semble confondre simplicité de compréhension et réutilisabilité. A partir de là, ça devient un dialogue de sourd. Mais sinon, dans le fond, sur l'exemple donné, je te rejoins. Il serait plus générique d'encapsuler le code. Mais ça n'en fait pas un programme plus simple à comprendre. D'ailleurs, l'encapsulation en cascade peut elle aussi poser des problèmes de compréhension du code.
En effet, je sens un problème de communication. Désolé.
La simplicité de compréhension ne se borne pas au cas local. Il est vrai que la simplicité que je critique ne se limite pas à ces deux fonctions. Elle englobe tout le produit de traitement d'image. Quand je vois un tel code (en général, je commence par la couche haute avant de descendre pour savoir si on n'aurait pas des fuites de ressources), je dois accorder plus d'attention pour comprendre ce qu'il fait. Cela vaut aussi bien pour la maintenance (a-t-on oublié des cas?), que pour son utilisation.

Et justement, son utilisation est à 100% embarquée dans du code qui continue à faire la même chose. Ce code que j'ai montré est le plus simple car tout au fond des appels. Quand on maintiens les couches au dessus, (qui suivent la même politique, détail très important), c'est vite l'enfer car il faut vérifier les cas remontés par cette partie, plus ceux remontés par les autres parties employées. Là, on a constitué une opération plus ou moins simple à appréhender, et on recommence en l'utilisant à un niveau supérieur. Mon expérience est que la complexité explose et qu'il y a des potentiels de fuites assez importants si un erreur de programmation est bel et bien détectée.

Le problème de ce type de code est le parasitage par la programmation défensive qui rend vite tout plus compliqué.
get_size() fait du défensif. Il est localement assez simple. get_pixel fait du défensif, il serait presque simple, sauf qu'il appelle une fonction qui elle-même fait du défensif, ce qui implique une complexification du code de get_pixel. get_region fait du défensif à son niveau et appelle d'autres fonctions qui font du défensif (get_size(), get_pixel()).

S'il y a des raccourcis que je prends, c'est lié au fait que j'affirme que grâce à class+private+constructeur, j'ai moyen d'éliminer une part non négligeable du défensif, ce qui permet d'avoir des fonctions plus simples à chaque niveau. Avec les exceptions, on peut encore aller plus loin : si on a un objet bandeau, alors il ne peut que être valide, et alors nul besoin de tester des choses assurées par construction du programme.
6  1 
Avatar de JolyLoic
Rédacteur/Modérateur https://www.developpez.com
Le 22/04/2016 à 0:02
Citation Envoyé par RPGamer Voir le message
Tout dépend des besoins. Pour programmer un MCU dans l'aviation par exemple on choisira le C pour obtenir un exécutable plus léger, moins groumant en RAM, plus performant et surtout complètement prédictible dans un contexte critique car le C++ fait des choses derrière le dos du programmeurs qui ne sont pas toujours souhaitables.
Il n'y a pas de bonne raison pour ça, sauf que les compilateurs C++ sont moins présents, moins robustes et moins certifiés que les compilateurs C. Mais ça n'empêche pas des entreprises travaillant dans l'embarqué d'utiliser du C++ sur des aspects safety-critical. On peut citer Lockheed Martin, qui a par exemple publié des règles de codage en C++ (http://www.stroustrup.com/JSF-AV-rules.pdf), ou le Mars Rover qui contient à la fois de C et du C++ (et on aura du mal à me faire croire que ces machines ont de la mémoire et de l'énergie à revendre...).
5  0 
Avatar de Médinoc
Expert éminent sénior https://www.developpez.com
Le 26/04/2016 à 14:52
C++ est ce qui permet de ne payer que pour ce qu'on utilise, tant en place mémoire qu'en vitesse.
Et le unique_ptr<> est l'une des fonctionnalités les moins chères et les plus utiles du C++: Un pointeur transférable, mais garanti n'avoir qu'un seul "propriétaire", et gérant la désallocation automatiquement.

C'est le meilleur moyen d'écrire du code exception-safe, absolument indispensable.
5  0 
Avatar de Luc Hermitte
Expert éminent sénior https://www.developpez.com
Le 27/04/2016 à 12:04
Citation Envoyé par AoCannaille Voir le message
Il en fera moins, donc plus vite. Il n'appelle pas la pile de constructeur dont hérite un objet. Les constructeurs implémentés sont potentiellement utile, ceux "par défaut" font juste un appel de fonction et un changement de contexte pour rien.

Enfin bon, mis à part cette seule exception; je ne vois rien d'autre, mais bon, je ne suis pas un spécialiste du fonctionnement profond de la mémoire en C ^^
Tu compares des choux et des carottes.
Si tu as besoin de construire ton objet (histoire de positionner l'invariant "est dans un état utilisable", alors il te faut le faire. New est donc équivalent à malloc + construction
Si tu n'en a pas besoin (i.e. parce que l'objet est un POD -- je simplifie), alors new ne fera rien de plus qu'un malloc.

Bref, tu paies avec new la même chose que ce que tu dois payer avec malloc. Si maintenant tu t'amuses à dé-PODifier tes agrégats de données dépourvues d'invariants pour le plaisir de faire semblant de faire de l'OO ... le prix inutile, c'est pas la faute de new.

S'il y a critique à faire, potentiellement, new pourrait appeler malloc de façon mal inlinée et pas une tierce fonction interne sur laquelle malloc repose également. OK, on paierait quelques petits cycles de plus à chaque allocation dans une telle situation.
5  0 
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 28/04/2016 à 12:41
malloc est tellement différent de new qu'il peut être utilisé pour le surcharger et qu'il est utilisé en interne dans certaines implémentations
http://en.cppreference.com/w/cpp/mem...w/operator_new
http://stackoverflow.com/questions/2...oc-free#240308
En fait la seule différence c'est vraiment l'appel au constructeur de la part de new après l'allocation. Donc si t'as des constructeurs triviaux/POD (ce qui est le cas en C où tu ne peux pas avoir autre chose), ça change strictement rien. Si t'as un constructeur non trivial, ben tu le payes.
5  0 
Avatar de ternel
Expert éminent sénior https://www.developpez.com
Le 20/04/2016 à 10:37
auto, car tant qu'a faire, utiliser la déduction de type.
Il aurait pu écrire bool concept LessThanComparable<typename T> {bool operator<(T, T);}.

Cela dit, je crois que la syntaxe proposée était plutot:
Code : Sélectionner tout
1
2
3
4
template<typename T>
concept bool LessThanComparable = requires(T a, T b) {
    { a < b } -> bool;
};
les deux mots clés sont requires et concept. la fonction est nécessairement bool.

Regardez par exemple sur cppreference.com pour la proposition actuelle de Concepts Technical Specification ISO/IEC TS 19217:2015.

La proposition est suffisamment intéressante à mon gout, elle permet de spécifier des attentes plus complexes, telles que "dispose de begin et end", "dispose de size()", ou encore est un appelable avec tels arguments.
Je dois dire que j'ai récemment écrit une bibliothèque de manipulation de fonctions mathématiques (somme, produit, composition, etc) et qu'un concept tel que callable_as<arg1, arg2> m'aurait grandement arrangé.
La moitié du code de cette bibliothèque consiste précisément à me donner cette capacité, au prix d'appel de deux classes de traits (et sept spécialisations chacune), de pleins de static_assert.

Avec les concepts, je n'aurai eu qu'a écrire une template de concept, et c'est tout.
4  0 
Avatar de Ehonn
Membre chevronné https://www.developpez.com
Le 20/04/2016 à 13:52
Oui, le langage devient de plus en plus complet / complexe.
Mais du coup son utilisation devient plus simple (et l'apprentissage de son utilisation aussi).

Les débutants n'ont pas / plus besoin d'apprendre les choses compliquées.
Pour donner un exemple avec les concepts : l'apprentissage et l'utilisation des concepts est beaucoup plus simple que celles de SFINAE.
Certains programmes qui étaient compliqués peuvent être réécrits en programmes relativement simples (même pour les débutants).
4  0 
Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web