Cette page vous a-t-elle été utile ?
Votre avis sur ce contenu est important. N'hésitez pas à nous faire part de vos commentaires.
Vous avez d'autres commentaires ?
1500 caractères restants
Exporter (0) Imprimer
Développer tout
Cet article a fait l'objet d'une traduction manuelle. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source

Prise en charge des fonctionnalités C++11 (Modern C++)

Cet article décrit les fonctionnalités C++11 dans Visual C++.

Visual C++ dans Visual Studio 2010 a implémenté de nombreuses fonctionnalités définies dans la spécification du langage principal C++11, et Visual C++ dans Visual Studio 2012 en a ajouté d'autres. Visual C++ dans Visual Studio 2013 étend encore cette couverture, et prend également en charge certaines fonctionnalités de la bibliothèque C++14. Le tableau suivant répertorie les fonctionnalités du langage principal C++11, ainsi que leur état d'implémentation dans Visual C++ de Visual Studio 2010, Visual C++ dans Visual Studio 2012 et Visual C++ dans Visual Studio 2013.

Fonctionnalités du langage principal C++11

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Références rvalue v0.1, v1.0, v2.0, v2.1, v3.0

v2.0

v2.1*

v2.1*

Qualificateurs ref

Non

Non

Non

Initialiseurs de membres de données non statiques

Non

Non

Oui

Modèles variadiques v0.9, v1.0

Non

Non

Oui

Listes d'initialiseurs

Non

Non

Oui

static_assert

Oui

Oui

Oui

auto v0.9, v1.0

v1.0

v1.0

v1.0

Types de retour de fin

Oui

Oui

Oui

Lambdas v0.9, v1.0, v1.1

v1.0

v1.1

v1.1

decltype v1.0, v1.1

v1.0

v1.1**

v1.1

Crochets angulaires à droite

Oui

Oui

Oui

Arguments template par défaut pour les modèles de fonction

Non

Non

Oui

Expression SFINAE

Non

Non

Non

Modèles d'alias

Non

Non

Oui

Modèles extern

Oui

Oui

Oui

nullptr

Oui

Oui

Oui

Enums fortement typés

partial

Oui

Oui

Enums déclarés avec anticipation

Non

Oui

Oui

Attributs

Non

Non

Non

constexpr

Non

Non

Non

Alignement

TR1

partial

partial

Constructeurs de délégation

Non

Non

Oui

Constructeurs hérités

Non

Non

Non

Opérateurs de conversion explicites

Non

Non

Oui

char16_t/char32_t

Non

Non

Non

Littéraux de chaîne Unicode

Non

Non

Non

Littéraux de chaîne bruts

Non

Non

Oui

Noms de caractère universel dans les littéraux

Non

Non

Non

Littéraux définis par l'utilisateur

Non

Non

Non

Types de disposition standard et types triviaux

Non

Oui

Oui

Fonctions utilisées par défaut et supprimées

Non

Non

Oui*

Déclarations friend étendues

Oui

Oui

Oui

Sizeof étendu

Non

Non

Non

Espaces de noms Inline

Non

Non

Non

Unions illimitées

Non

Non

Non

Types locaux et sans nom comme arguments template

Oui

Oui

Oui

Boucle for basée sur une plage

Non

Oui

Oui

override et final v0.8, v0.9, v1.0

partial

Oui

Oui

Prise en charge minimale du récupérateur de mémoire

Oui

Oui

Oui

noexcept

Non

Non

Non

[go to top]

Fonctionnalités du langage principal C++11 : concurrence

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Points de séquence reformulés

N/A

N/A

N/A

Éléments atomiques

Non

Oui

Oui

Comparaison et échange forts

Non

Oui

Oui

Délimitations bidirectionnelles

Non

Oui

Oui

Modèle de mémoire

N/A

N/A

N/A

Classement des dépendances de données

Non

Oui

Oui

Classement des dépendances de données : annotation de fonction

Non

Non

Non

exception_ptr

Oui

Oui

Oui

quick_exit

Non

Non

Non

Éléments atomiques des manipulateurs de signal

Non

Non

Non

Stockage local des threads

partial

partial

partial

Statiques magiques

Non

Non

Non

[go to top]

Fonctionnalités du langage principal C++11 : C99

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

__func__

partial

partial

partial

Préprocesseur C99

partial

partial

partial

long long

Oui

Oui

Oui

Types d'entiers étendus

N/A

N/A

N/A

[go to top]

Remarque Remarque

Les désignations de version (v0.1, v1.0, v2.0, v2.1 et v3.0) figurant dans les descriptions suivantes ont été inventées uniquement pour montrer l'évolution de C++11. Le standard lui-même ne les utilise pas.

Le document N1610 « Clarification of Initialization of Class Objects by rvalues » était une première tentative visant à permettre l'utilisation d'une sémantique de déplacement sans références rvalue. Dans cette discussion, appelons cela « références rvalue v0.1 ». Ces références ont été remplacées par les « références rvalue v1.0 ». Les « références rvalue v2.0 », sur lesquelles repose le travail dans Visual C++ dans Visual Studio 2010, interdit aux références rvalue de créer une liaison avec des valeurs lvalue et résout ainsi un problème de sécurité majeur. " Les références rvalue v2.1 » affinent cette règle. Tenez compte de vector<string>::push_back(), qui a les surcharges push_back(const string&) et push_back(string&&), et l'appel v.push_back("strval"). L'expression "strval" est un littéral de chaîne et représente une lvalue. (Les autres littéraux, par exemple le nombre entier 1 729, sont des rvalues, mais les littéraux de chaîne sont spéciaux car il s'agit de tableaux.) Les règles des « références rvalue v2.0 » révèlent que string&& ne peut pas créer de liaison avec "strval" car "strval" est une lvalue et que push_back(const string&) est donc la seule surcharge valide. Cela crée une std::stringtemporaire, la copie dans le vecteur, puis détruit la std::stringtemporaire, qui n'était pas très efficace. Les règles des « références rvalue v2.1 » identifient que la liaison de string&& avec "strval" créerait une std::stringtemporaire, et que temporaire est une rvalue. Par conséquent, push_back(const string&) et push_back(string&&) sont viables et push_back(string&&) est préféré. Une std::string temporaire est construite, puis déplacée dans le vecteur. Cette méthode est plus efficace.

Les « références rvalue v3.0 » ajoutent des règles pour générer automatiquement des constructeurs de déplacement et des opérateurs d'assignation de déplacement sous certaines conditions. Toutefois, cela n'est pas implémenté dans Visual C++ dans Visual Studio 2013, en raison des contraintes de temps et de ressources.

[go to top]

Après le vote des fonctions lambda dans la feuille de travail (version « 0.9 ») et l'ajout des expressions lambda mutables (version « 1.0 »), le Comité de normalisation a révisé le libellé. Cela a produit des expressions lambda version « 1.1 », qui sont maintenant pleinement prises en charge. Les lambdas v1.1 clarifient ce qui doit se produire en cas de référence à des membres statiques ou des lambdas imbriqués. Cela corrige les problèmes déclenchés par les expressions lambda complexes. En outre, les expressions lambda sans état sont maintenant convertissables en pointeurs de fonction. Ce n'est pas dans la formulation N2927, mais est considéré comme faisant partie, néanmoins, des expressions lambda v1.1. C++11 5.1.2 [expr.prim.lambda]/6 a la description suivante : « Le type de clôture d'une lambda-expression sans lambda-capture a une fonction de conversion const non explicite non virtuelle publique de conversion de pointeur en fonction ayant les mêmes types de paramètre et de retour que l'opérateur d'appel de fonction du type de la clôture. La valeur retournée par cette fonction de conversion est l'adresse d'une fonction qui, lorsqu'elle est appelée, a le même effet que l'appel de l'opérateur d'appel de fonction du type de la clôture ». (L'implémentation Visual C++ dans Visual Studio 2012 est encore mieux, car les expressions lambdas sans état convertibles sont devenues des pointeurs de fonction qui ont des conventions d'appel aléatoires. Ceci est important lorsque vous utilisez des API qui attendent des éléments comme des pointeurs de fonction __stdcall.)

[go to top]

Après le vote de decltype dans la feuille de travail (version 1.0), il a reçu une correction légère mais importante à la dernière minute (version 1.1). Cela présente un grand intérêt pour les programmeurs qui travaillent dans STL et Boost.

[go to top]

Les enums fortement typés étaient partiellement pris en charge dans Visual C++ dans Visual Studio 2010 (en particulier, la partie sur les types sous-jacents spécifiés explicitement). Ils sont désormais totalement implémentés dans Visual Studio, et la sémantique C++11 relative aux enums déclarés avec anticipation est également totalement implémentée.

[go to top]

Les mots clés du langage principal alignas/alignof de la proposition d'alignement qui a été votée dans la feuille de travail ne sont pas implémentés. Visual C++ dans Visual Studio 2010 avait aligned_storage à partir de TR1. Visual C++ dans Visual Studio 2012 a ajouté aligned_union et std::align() dans la bibliothèque standard et des problèmes importants ont été résolus dans Visual C++ dans Visual Studio 2013.

[go to top]

Les modifications exposées issues du document N2342 « POD's Revisited; Resolving Core Issue 568 (Revision 5) » sont les ajouts de is_trivial et is_standard_layout à <type_traits> de la bibliothèque STL (Standard Template Library). (N2342 a retouché une grande partie du libellé du langage principal, mais aucun changement de compilateur n'est nécessaire.) Ces caractéristiques de type étaient disponibles dans Visual C++ de Visual Studio 2010, mais elles ont seulement dupliqué is_pod. Par conséquent, la table évoquée plus haut dans ce document indiquait « Non » pour la prise en charge. Ils sont maintenant actionnés par des raccordements de compilateur qui permettent de proposer des réponses exactes.

Le common_type<> de la bibliothèque STL a fait l'objet d'un correctif fort attendu dans Visual C++ dans Visual Studio 2013. La spécification C++11 pour common_type<> avait des conséquences inattendues et indésirables ; en particulier, common_type<int, int>::type retournait int&&. Par conséquent, Visual C++ dans Visual Studio 2013 implémente la Résolution proposée pour le problème 2141 du groupe de travail sur les bibliothèques, qui fait que common_type<int, int>::type retourne int.

Effet secondaire de cette modification : le cas d'identité ne s'exécute plus (common_type<T> ne produit pas toujours le type T). Cela est conforme à la résolution proposée, mais interrompt le code qui était fondé sur le comportement précédent.

Si une caractéristique de type identité est requise, n'utilisez pas la caractéristique std::identity non standard définie dans <type_traits>, car elle ne fonctionnera pas pour <void>. À la place, implémentez votre propre caractéristique de type d'identité pour répondre à vos besoins. Voici un exemple :

template <typename T> struct Identity {
    typedef T type;
};
RemarqueRemarque

Pour connaître les autres nouveautés, consultez Modifications avec rupture dans Visual C++.

[go to top]

Celles-ci sont maintenant prises en charge, mais avec cette exception : pour les fonctions utilisées par défaut, l'utilisation de =default pour demander le déplacement de constructeurs et d'opérateurs d'assignation n'est pas prise en charge. Les copies et les déplacements n'interagissent pas précisément comme le prétend la norme. Par exemple, la suppression des déplacements est spécifiée pour supprimer également les copies, mais ce n'est pas le cas de Visual C++ dans Visual Studio 2013.

Pour plus d'informations sur l'utilisation des fonctions utilisées par défaut et supprimées, consultez Définitions de fonction C++.

[go to top]

L'évolution a été brève, mais complexe. Initialement, dans la version 0.8, il existait les attributs [[override]], [[hiding]] et [[base_check]]. Puis, dans la version 0.9, les attributs ont été supprimés et remplacés par les mots clés contextuels. Enfin, dans la version 1.0, ils ont été réduits en « final » sur les classes, ainsi qu'en « override » et « final » sur les fonctions. Cela en fait une extension ascendante, car Visual C++ dans Visual Studio 2010 prenait déjà en charge cette syntaxe « override » sur les fonctions et avait une sémantique assez proche de celle de C++11. « final » a également été pris en charge, mais sous l'orthographe différente « sealed ». L'orthographe et la sémantique standard de « override » et « final » sont maintenant complètement prises en charge. Pour plus d’informations, voir Spécificateur de substitution et Spécificateur final.

[go to top]

Le tableau Core Language Feature Table: C99 indique une implémentation « partielle » pour deux éléments. Pour l'identificateur prédéfini __func__, la mention « Partielle » figure dans le tableau car une prise en charge est fournie pour les extensions non standard __FUNCDNAME__, __FUNCSIG__ et __FUNCTION__. Pour plus d'informations, voir Macros prédéfinies. Pour les règles du préprocesseur C99, la mention « Partielle » est répertoriée car les macros variadiques sont prises en charge. Pour plus d'informations, voir Macros Variadic.

[go to top]

Cela couvre le langage principal. Comme pour la bibliothèque standard C++11, nous n'avons pas une grande table de comparaison des fonctionnalités, mais Visual C++ dans Visual Studio 2012 les a implémentées, avec deux exceptions. Tout d'abord, lorsqu'une fonctionnalité de bibliothèque dépendait d'une fonctionnalité qui manquait dans le compilateur, celle-ci était simulée, par exemple, des modèles variadiques simulés pour make_shared<T>(), ou n'était pas implémentée. (Il n'y avait que quelques cas, principalement <initializer_list>, qui sont désormais totalement implémentés dans Visual C++ dans Visual Studio 2013.) À très peu d'exceptions, C99 a été implémenté dans les en-têtes wrapper Visual C++ dans Visual Studio 2013 et C++ fournis. Pour plus d'informations, voir Prise en charge de la bibliothèque C99 dans Visual Studio 2013.

Voici une liste partielle des modifications dans Visual C++ dans Visual Studio 2012 et Visual C++ dans Visual Studio 2013 :

Emplacement : comme requis par C++11, emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() sont implémentés dans tous les conteneurs pour les nombres « arbitraires » d'arguments (consultez la section sur les « variadiques simulés »). Par exemple, vector<T> a « template <typename... Args> void emplace_back(Args&&... args) » qui construit directement un élément de type T à l'arrière du vecteur à partir d'un nombre arbitraire d'arguments arbitraires, parfaitement transférés. Cela peut être plus efficace que push_back(T&&), qui comporterait une construction et une destruction de déplacements supplémentaires.

Variadiques : Visual C++ dans Visual Studio 2012 comportait un nouveau schéma pour simuler les modèles de variadiques. Dans Visual C++ dans Visual Studio 2013, les simulations ont disparu et les modèles variadiques sont entièrement implémentés. Si votre code dépend de l'ancien comportement des modèles variadiques simulés, vous devez le corriger. Toutefois, l'implémentation de modèles variadiques réels a amélioré les délais de compilation et réduit la consommation de la mémoire du compilateur.

Opérateurs de conversion explicites : dans le langage principal, les opérateurs de conversion explicites sont une fonctionnalité générale ; par exemple, vous pouvez avoir explicit operator MyClass(). Toutefois, la bibliothèque standard n'utilise actuellement qu'un seul formulaire : explicit operator bool(), qui rend les classes booléennes testables en toute sécurité. (Un simple « operator bool() » est notoirement dangereux.) Auparavant, Visual C++ simulait explicit operator bool() avec operator pointer-to-member(), ce qui a entraîné plusieurs problèmes et un léger manque d'efficacité. À présent, cette solution de contournement « fausse valeur booléenne » est complètement supprimée.

Caractère arbitraire : uniform_int_distribution est maintenant parfaitement impartial et shuffle() est implémenté dans <algorithm>, qui accepte directement les générateurs de nombres aléatoires uniformes comme mersenne_twister.

Résistance aux opérateurs d'adresse surchargés : C++98/03 interdisait à un élément de conteneur STL de surcharger son opérateur d'adresse. C'est ainsi que les classes comme CComPtr agissent, afin que les classes d'assistance comme CAdapt soient obligées de protéger la bibliothèque STL de telles surcharges. Pendant le développement de Visual C++ dans Visual Studio 2010, les modifications apportées à STL provoquent le rejet des opérateurs address-of surchargés dans davantage de situations. C++11 a modifié les spécifications visant à rendre les opérateurs d'adresse surchargés acceptables. C++11 et Visual C++ dans Visual Studio 2010 fournissent la fonction d'assistance std::addressof(), qui peut obtenir l'adresse exacte d'un objet, quelle que soit la surcharge d'opérateur. Avant la parution de Visual C++ dans Visual Studio 2010, nous avons essayé de remplacer les occurrences de « &elem » par « std::addressof(elem) », qui présente la résistance appropriée. Visual C++ dans Visual Studio 2012 est allé plus loin, pour que les classes qui surchargent leur opérateur address-of soient utilisables dans l'ensemble de la bibliothèque STL.

Visual C++ dans Visual Studio 2012 a dépassé C++11 de plusieurs façons :

Itérateurs SCARY : comme le permet (sans l'exiger) la norme C++11, les itérateurs SCARY ont été implémentés, conformément à ce qui est décrit dans N2911 « Minimizing Dependencies within Generic Classes for Faster and Smaller Programs » et dans N2980 « SCARY Iterator Assignment and Initialization, Revision 1 ».

Filesystem : l'en-tête <filesystem> de la proposition TR2 a été ajouté. Il offre recursive_directory_iterator et d'autres fonctionnalités intéressantes. Avant que le travail sur TR2 ne soit gelé car C++0x a fonctionné très tard et a été remplacé par C++11, la proposition de 2006 était dérivée de Boost.Filesystem V2. Il a ensuite évolué vers Boost.Filesystem V3, mais cela n'est pas implémenté dans Visual C++ dans Visual Studio 2012.

Et une optimisation importante ! Tous nos conteneurs sont désormais réduits de façon optimale au vu de leurs représentations actuelles. Cela fait référence aux objets conteneurs eux-mêmes, pas aux contenus vers lesquels ils pointent. Par exemple, std::vector contient trois pointeurs bruts. En Visual C++ dans Visual Studio 2010, le mode release x86, std::vector était de 16 octets. Dans Visual C++ dans Visual Studio 2012, il est de 12 octets, ce qui est réduit de façon optimale. La belle affaire : si vous avez 100 000 vecteurs dans votre programme, Visual C++ dans Visual Studio 2012 vous fait gagner 400 000 octets. L'utilisation réduite de la mémoire permet d'économiser de l'espace et du temps.

Cela a été accompli en évitant le stockage d'allocateurs et comparateurs vides, car std::allocator et std::less sont sans état. (Ces optimisations sont activées pour les allocateurs/comparateurs personnalisés, tant qu'elles sont sans état. Évidemment, le stockage d'allocateurs/de comparateurs avec état est inévitable, mais il s'agit de cas très rares.)

Visual C++ dans Visual Studio 2013 va encore au-delà de C++11 pour implémenter certaines fonctionnalités clés de bibliothèque C++14 :

  • « Foncteurs d'opérateurs transparents » less<>, greater<>, plus<>, multiplies<>, et ainsi de suite.

  • make_unique<T>(args...) et make_unique<T[]>(n)

  • Fonctions non membres cbegin()/cend(), rbegin()/rend() et crbegin()/crend().

[go to top]

Ajouts de la communauté

AJOUTER
Afficher:
© 2015 Microsoft