Le nouveau design des articles est vraiment excellent !
Ne manque-t-il pas la partie I ?
Le nouveau design des articles est vraiment excellent !
Ne manque-t-il pas la partie I ?
La partie correspond à gcc 4.8. Elle n'est pas encore rédigée, elle est donc masquée
Pour rappel, si vous voulez participer à cet article et rédiger des parties (ou compléter des parties existantes), n'hésitez pas
Moi je veux bien t'aider, mais que manque-t-il ?
Voir le premier post : les parties "à faire" de gcc 4.4 et tout gcc 4.3. Et relire et compléter si nécessaire ce qui est déjà écrit
J'ai attaqué la partie move semantic, donc ça c'est bon
Les énumérations simples (dites faiblement typées) se déclarent ainsi :
Elles s'utilisent comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 enum Direction { Nord,// = 0 Est,// = 1 Sud,// = 2 Ouest// = 3 };
Ces énumérations sont implicitement transformables en entiers, ce qui permet comme le montre le code ci-dessus de faire des opérations incongrues (multiplier le sud par le nord ne poserait aucun problème au compilateur), et même d'arriver à des valeurs même pas comprises dans la définition de l'énumération.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Direction d = Nord; d = 2;//ce qui sous entend d = Sud int i = d*Ouest;//i = 8 d = (d*3)%Sud;//d = Nord d = Ouest; ++d;//d = 5 => boom, mais le compilateur ne dira rien parce que c'est tout à fait légal
Le C++11 apporte une solution pour remédier à cela : les énumérations fortement typées. Elle se définissent en ajoutant le mot-clé class devant le nom de l'énumération :
L'utilisation est plus claire et plus sécurisée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 enum class Direction { Nord, Est, Sud, Ouest };
Bien sûr, les énumérations faiblement typées n'en sont pas pour autant obsolètes : elles restent nécessaires pour utiliser les flags. Ces deux typages (faible et fort) sont donc complémentaires.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 Direction d = Direction::Sud//ok Direction d2 = Nord;//error: Nord est inconnu d = 2;//error: on ne mélange pas les choux et les carottes d = (d*3)%Sud;//error ++d;//error d = Ouest;//error: Nord est inconnu d = Direction::Est;//ok int i = d*Ouest;//error int i2 = static_cast<int>(d);//ok i2 = 1, transformation explicite
Copié collé depuis le chat :
"définissent" -> c'est pas une définition, c'est un exemplene pas parler des valeurs par défaut des énums dans le premier code, on n'en parle plus aprèsdans le second code, séparer le code d'utilisation correcte et le code problématique(avant que quelqu'un fait la remarque : il manque des choses (les underlying types en particulier), c'est pour la suite)"les énumérations faiblement typées n'en sont pas pour autant obsolètes : elles restent nécessaires pour utiliser les flags." On peut pas faire les flags avec les enums class ? Et si on parle des flags, faut donner du code d'explication
Note aussi qu'on peut :
- expliciter le type physique sous-jacent à l'énumération (int par défaut) pour les deux types d'énumération :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 enum /*class*/ Direction : unsigned char { Nord, Est, Sud, Ouest };- faire une déclaration anticipée d'une énumération. Il faut alors préciser le type sous-jacent, sauf si l'on déclare une énumération fortement typée (qui aura alors le type par défaut, int) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 enum Direction : unsigned char; enum class Direction ; // Direction est de type int enum Direction; // erreur : c'est interdit
Edit : grillé par gbdivers, du coup j'ai l'air bête...
Pour un enum normal (98), Il n'y a pas de pré-fixage par le nom de l'enum comme tu l'as écris, germinolegrand, en ligne 3 du 2e code.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
@kalith: déclaration anticipée : déjà fait et dans une autre version : http://cpp.developpez.com/redaction/.../cpp11/#LIII-C
@luc: merci, rectifié.
@gbdivers:
#1: rectifié
#2: si justement j'en parle après dans les calculs faits sur les valeurs d'enums qui sont justement basées sur ces valeurs, donc je les précise pour pouvoir comprendre le résultat des calculs du 2e code.
#3: rectifié
#4: non, on ne peut pas sans cast de cast de cast . J'ai ajouté un lien puisque tu y tiens () et je signale au passage que tu les utilises ailleurs sans vergogne ^^ (http://cpp.developpez.com/redaction/.../cpp11/#LIII-D) d'ailleurs tu définis des opérateurs inutiles dans ton code
Peut-être pour illustrer les constexpr eut-il été préférable de montrer un pow implémenté en constexpr ? (très simple)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 template <class T> constrexpr T pow(const T t, const unsigned int n) { return n ? t*pow(t, n - 1): 1; }
Un 'r' en trop à "constrexpr" dans mon message précédent.
--------------------
Le type sous-jacent des énumérations
Les énumérations sont converties à la compilation vers un type entier. Par défaut ce type est celui du plus petit type entier signé capable de contenir toutes les valeurs de l'énumération.
Afin de forcer ce type à int, il était d'usage d'ajouter cette valeur inutile :
Le C++11 introduit la définition explicite du type sous-jacent. Ainsi, il est possible de choisir le type sous-jacent à ses énumérations, ce qui offre de plus la possibilité d'utiliser des types non-signés :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 enum MY_INT_ENUM { Nord, Sud, Ouest, Est, MY_INT_ENUM_FORCE_32BITS = 0xffffffff; };
Ceci se marie tout à fait avec les énumérations fortement typées :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 enum MY_USHORT_ENUM : unsigned short { Nord, Sud, Ouest, Est, };
Il est garanti que sizeof(directionDuSoleil) == sizeof(unsigned short).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 enum class Direction : unsigned short { Nord, Sud, Ouest, Est, }; Direction directionDuSoleil = Sud;
La programmation générique n'est pas en reste avec cette nouvelle fonctionnalité, puisque le header <type_traits> fournit le trait std::underlying_type qui permet de récupérer le type sous-jacent de l'énumération :
---------------
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <type_traits> enum class Vase : unsigned int { PleinDeFuites = 0; BonEtat = 1; }; template <class T> std::underlying_type<T> remplir(T etat, std::underlying_type<T> remplissage) { return static_cast<std::underlying_type<T>>(etat)*remplissage; } //[...] if(remplir(Vase::PleinDeFuites, 90) == 0) std::cout << "Je vous l'avais dit, c'est pas avec ça qu'on éteindra un incendie !" << std::endl;
Remarques bienvenues.
Ajouté l'exemple sur constexpr et les enums, avec quelques corrections :
- j'ai changer les noms de variables de pow, que ça soit similaire à la fonction std::pow
- j'ai ajouté la version avec template récursif pour pow
- j'ai retiré le template de la fonction constexpr pour que la distinction soit plus nette avec la version avec template (même si bien sur, il faudrait utiliser les template... voir utiliser common_type)
- pour le dernier exemple des enum class avec sizeof, j'ai utilisé le code de cppreference, le tiens me semblait moins claire (en fait, il faudrait même faire comme pour l'exemple sur les constexpr, avoir un code copié-collable-compilable)
- il manque un petit texte pour la porté des enum class vs les enums
Merci
Typo :
=> soit virer le "que" soit rajouter un "ne"Les chaînes littérales sont concaténées que si elles ont le même préfixe ou que l'une des deux chaînes n'a pas de préfixe :
Ajout d'une petite note pour gcc 4.8 sur les premières nouvelles fonctionnalités implémentées : GCC 4.8. Cela sera détaillé par la suite
GCC 4.8 vient de sortir.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager