02 déc. 2010

Le futur standard C++ : apparté

Je sais que je ne devrais plus toucher au sujet, mais voilà qu'enfin, une personne du comité de normalisation du C++ a enfin compris ma détresse. De quoi est-ce que je parle ? Et bien, tout simplement d'un article assez ancien, paru sur ce blog, et qui a déjà connu plusieurs suites. Tout a commencé il y a quatre (courtes ?) années, par ce billet : Etude du C++ Technical Report 1 - reference_wrapper. Deux errata ont suivi : le premier paru quelques jours plus tard, donne une idée du noeud du problème : il y a un problème dans la norme C++. Le second fait état d'une conversation avec Pete Becker (l'éditeur du comité de normalisation C++ la personne chargée à l'heure actuelle de mettre à jour le document normatif), qui contredit un peu mon argumentaire précédent. Enfin, le dernier billet est une vérification de l'implémentation de std::tr1::reference_wrapper<> dans le Service Pack 1 de Visual Studio .Net 2008.

Il fallait une conclusion à tout ça, et j'espère que ce billet l'apportera enfin. Un élément nouveau est récemment venu apporter de l'eau à mon moulin.

Vous le savez peut-être, le comité de normalisation du C++ avance maintenant en ligne droite, avec pour point de mire le texte final de la norme, qui sera ensuite approuvé par ANSI/ISO. Pour l'heure, les valeureux chevaliers corrigent les défauts du texte existant (la dernière version de ce texte est disponible en PDF sur le site du WG21. C'est un document de plus de 1000 pages, avec de nombreuses notes d'édition).

Bientôt aura lieu un nouveau meeting - le dernier de l'année 2010. Comme le prévoit les process du groupe, les documents nouveaux qui serviront de support à ce meeting ont été mis en ligne - c'est le mailing pre-réunion 2010-10. Parmis ces documents important figure une proposition qui, si elle était adoptée, pousserais fortement les classes std::unary_function<> et std::binary_function<> vers la sortie : ces deux classes seraient alors marquées comme étant dépréciées, et toutes les utilisations de ces classes seraient supprimées de la librairie standard. Il faut noter que la décision a dors et déjà été prise : ce document ne fait que la formaliser afin qu'elle soit votée en bonne forme.

Cette modification a plusieurs raisons, mais le principal reproche qui est fait à ces classes est qu'elle sont insufisament spécifiées - et de cette spécification insuffisantes sont nées plusieurs problèmes, qui ont vraiment pris de l'ampleur avec le TR1. En effet, dans le TR1, ces classes ont été héritées de manière régulière pour construire les classes tr1::bind<> et bien d'autres, dont... tr1::reference_wrapper<>. Et de ces utilisations nait un problème sévère.

Je me permet de traduire une partie du document, intitulé N3145: Deprecating unary_function and binary_function et écrit par Daniel Krügler (l'emphase est de mon fait).

Notre expérience avec les concepts nous a donné l'assurance qu'il est rarement nécessaire de dépendre de relations spécifiques entre les classes de base et les classes dérivées lorsque la disponibilité de types et de fonctions suffit. Les nouveaux outils du langage nous permettent de déduire l'existence de noms de types dans les classes même en l'absence de conceptes supportés par le langage, ce qui diminuerais grandement le couplage entre elles. Un autre avantage du remplacement de l'héritage par des types associés tiens en la réduction du nombre de cas où l'on rencontre une ambiguité. Celà peut arriver aisément si un type dérive à la fois de unary_function et de binary_function (ce qui a du sens si le foncteur est à la fois un objet function unaire et binaire).

Dans toute la série d'article que j'ai composé à propos de tr1::reference_wrapper<>, l'ambiguité qui nait de la définition même de cette classe est un point nodal où se concentre tous le problème du manque de définition de unary_function et binary_function. Avec comme résultante le fait qu'aucun des compilateur existant ne définit correctement la classe tr1::reference_wrapper<> - non pas parce que les vendeurs de compilateurs font une grossière erreur, mais tout simplement parce que c'est impossible. La problématique est liée à la définition de tr1::reference_wrapper<>::result_type qui est ambigüe si le type paramètre est un foncteur dérivant à la fois de unary_function et binary_function (voir cet article). Cette ambiguité est un poison qui empêche toute implémentation correcte du TR1 (et, accéssoirement, de la future norme telle qu'elle est encore définie dans le draft courant).

Et voilà que la proposition de M. Kruegler élimine une partie du problème (tout n'est pas encore rêglé, parce que le papier ne traite pas de tr1::reference_wrapper<>::result_type). C'est une bonne nouvelle pour les utiilsateurs (pas si courant que ça, tant son usage est limité) de tr1::reference_wrapper<>. Et, ce qui est toujours bon pour l'égo, ça valide en grande partie l'analyse que j'ai mené il y a déjà 4 ans.

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

Fil des commentaires de ce billet