Passons donc en revue quelques-unes des nouvelles fonctionnalités du langage ainsi que les fonctionnalités existantes supprimées de C ++.
Fonctions C ++ existantes qui ont été supprimées
Suppression des trigraphes
Le jeu de caractères utilisé par le langage C++ comprend toutes les lettres en majuscules et en minuscules, tous les chiffres et les caractères suivants : . , ; : ! ? " ' + - ^ * % = & | ~ _ # / \ { } [ ] () < >
Malheureusement, certains environnements sont incapables de gérer quelques-uns de ces caractères. C'est pour résoudre ce problème que les trigraphes ont été créés.
En clair, les trigraphes sont des séquences de trois caractères commençant par deux points d'interrogation. Ils permettent de remplacer les caractères qui ne sont pas accessibles sur tous les environnements. Par exemple :
- ??= génère #
- ??- génère ~
- ??< génère {
Il est important de mentionner que tous les jeux de caractères source de C ++ sont compatibles avec l'ASCII 7 bits. Vous n'utiliserez donc sans doute jamais les trigraphes, à moins d'y être forcé. C’est ce point (la rareté d’utilisation) qui fait en sorte que dans la nouvelle version les trigraphes ne sont plus utilisés.
La suppression de ces séquences rendra la phase de traduction plus simple.
Suppression de “register”
Le mot clé "register", qui sert à déclarer les variables registre, a été déprécié dans la norme C ++ 11. Cette fois-ci, en C ++ 17, il a été supprimé. Il faut cependant noter que ce mot clé est toujours réservé et peut être réutilisé dans les futures révisions.
Suppression de l'opérateur obsolète ++
Les expressions post-préfixe et préfixe (++) ne sont plus valables pour les opérandes booléens.
Suppression des spécifications d'exception obsolètes
En C ++ 17, la spécification d'exception fait partie du système de type. Mais la norme comporte toujours une spécification d'exception ancienne et obsolète, qui ne semble pas être pratique et utilisée.
Par exemple:
Code C++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | void fooThrowsInteger(int x) throw(int) { printf_s("throw int\n"); if (x == 0) { throw 1; } } |
Suppression de auto_ptr
Le C ++ 11 nous fournit des pointeurs intelligents comme shared_ptr, weak_ptr et unique_ptr. En comparaison, auto_ptr, qui est plus ancien, s’est avéré bogué et a donc été considéré comme étant obsolète en C ++ 11. Dès lors, la suppression de C ++ 17 paraissait inévitable.
Presque toutes les fonctionnalités qui ont été abandonnées en C ++ 11 et remplacées par des composants plus récents ont été supprimées, bien que leurs noms soient toujours réservés.
Quelques nouveautés apportées par C++ 17
Spécifications d'exception
Dans les versions précédentes de C ++, les spécifications d'exception pour une fonction n'étaient pas associées au type de fonction. Dans ce cas, nous avons rencontré une erreur comme suit :
Code C++ : | Sélectionner tout |
1 2 3 4 5 6 | void (*t)(); void (**tt)() noexcept=&t; // error: can-not convert to // pointer to noexcept struct V { typedef void (*t)(); operator t(); }; void (*k)() noexcept = V(); // error: can-not convert to pointer to noexcept |
Mais maintenant, dans C ++ 17, la spécification d'exception est une partie de type système. Une des raisons importantes pour l'ajout de cette fonctionnalité est une possibilité de permettre une meilleure optimisation. En clair, vous pouvez utiliser le spécificateur "noexcept" pour déclarer qu'une fonction peut lancer quelque chose ou non.
Règles auto pour une initialisation directe de liste
Vous pouvez maintenant déclarer un paramètre de modèle non-type avec un espace réservé de type auto. En C ++ 11, nous sommes confrontés à ce problème étrange où auto x {1}; est déduit comme initializer_list. Ce problème est résolu dans la nouvelle norme, donc il sera déduit comme int.
Avant de continuer, il faut comprendre les deux méthodes d'initialisation de liste que sont l’initialisation par copie et l’initialisation directe.
Code C++ : | Sélectionner tout |
1 2 | auto a = foo(); // this is copy initialization auto a{foo}; // this is direct initialization, it initializes an initializer_list |
Pour une initialisation directe, C++ 17 introduit de nouvelles règles:
- pour une liste avec un seul élément, l'autodéduction déduira de cette entrée particulière ;
- pour une liste avec plusieurs éléments, l'autodéduction va générer une erreur.
Code C++ : | Sélectionner tout |
1 2 3 4 5 | auto a1 = { 21, 12 }; // decltype(a1) is std::initializer_list<int> auto a3{ 11, 3 }; // error: not a single element auto a2 = { 11, 3.0 }; // error: cannot deduce element type auto a4 = { 7 }; // decltype(a4) is std::initializer_list<int> auto a5{ 8 }; // decltype(a5) is int |
Static_assert sans message
Cette fonctionnalité mise à jour permet d'avoir une condition sans passer le message, ou vous pouvez dire que la déclaration static_assert ne nécessite plus de second argument. La version avec message est également disponible. Elle est compatible avec d'autres assertions telles que BOOST_STATIC_ASSERT.
Code C++ : | Sélectionner tout |
1 2 | static_assert(std::is_arithmetic_x<A>, "A should be arithmetic"); static_assert(std::is_arithmetic_x<A>); // no such message required in C++17 |
Conclusion
Bien entendu, cette liste est très loin d'être exhaustive ; le nombre de spécifications apportées par C++ 17 (1586 contre 1368 pour C++14) est un assez bon indicateur pour le rappeler. Les nouveautés s'imbriquent dans diverses catégories allant des changements dans la bibliothèque aux clarifications du langage.
Source : MycPlus
Et vous ?
Quelles sont les nouveautés apportées par C++17 qui vous intéressent le plus ?
Voir aussi :
Quels sont les EDI C/C++ les plus utilisés en 2018 ? Un développeur nous livre les résultats de son étude
Pourquoi les langages C et C++ auraient-ils encore de nombreuses années devant eux ? Donnez votre avis