IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

foreach tirera sa révérence avec Qt 5.9


Sujet :

Qt

  1. #1
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 618
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 618
    Points : 188 585
    Points
    188 585
    Par défaut foreach tirera sa révérence avec Qt 5.9
    Qt 4 a défini une macro Q_FOREACH (aussi accessible comme pseudo mot clé foreach) pour faciliter l’itération dans ses conteneurs (comme QList ou QStringList). Cependant, son mode de fonctionnement n’est pas idéal : tout le conteneur est copié dans une instance de QForeachContainer avant que la boucle commence effectivement, cette syntaxe n’est pas non plus compatible avec des tableaux C. Dès Qt 5.9 (ou un peu après), cette construction devrait être marquée comme obsolète dans Qt : C++11 propose une construction très similaire, qui sera dorénavant privilégiée (les développeurs de Qt peuvent maintenant utiliser cette nouvelle version de C++, la compatibilité avec C++03 n’étant plus garantie depuis la version 5.7).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Q_FOREACH(int i, container) // Dès Qt 4
    for (int i : container) // C++ 11
    De manière générale, cependant, foreach ne pose que peu de problèmes : l’instance de QForeachContainer n’est pas obligée de faire une copie en profondeur du conteneur sur lequel l’itération se passe (contrairement à une boucle utilisant directement l’API des itérateurs de la STL).

    Cette implémentation peut même être tirée à profit dans certains bouts de code : puisque l’itération se passe sur une copie du conteneur initial, il est possible d’ajouter des éléments dans ce conteneur initial sans affecter l’itération. Bien sûr, dans ce cas, une copie en profondeur doit avoir lieu, mais le code fonctionne (contrairement à sa version C++11).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Q_FOREACH(const QString &lang, languages)
        languages += getSynonymsFor(lang);
    Les vrais problèmes arrivent quand quelqu’un d’autre lit ce code, à cause de cette dépendance à un détail d’implémentation de Qt : la situation serait bien plus claire si le développeur avait pris le temps de copier le conteneur avant d’itérer (et de modifier le conteneur initial) — ou, si les modifications se limitent à l’ajout d’éléments à la fin, de s’assurer qu’aucune lecture n’aura lieu après la fin du conteneur au moment où la boucle débute. Cet exemple indique déjà qu’il ne sera pas si facile de migrer tout le code vers la construction “équivalente” de C++11 (remarquer de manière automatique ces cas particuliers serait très ardu).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const auto languagesCopy = languages; 
    for(const auto& lang : languagesCopy)
        languages += getSynonymsFor(lang);
    Au niveau de la performance, si le conteneur n’est pas défini comme constant, alors le compilateur C++ sera obligé d’effectuer une copie (comme Qt auparavant avec foreach). Pour éviter ce cas particulier, il est nécessaire d’en changer le type pour indiquer qu’il sera constant pendant l’itération : C++11 fournit la fonction std::as_const(), Qt 5.7 qAsConst(). Ainsi, la lisibilité du code est gardée, mais avec une performance idéale.
    De manière générale, utiliser foreach consomme une centaine d’octets de plus que la même boucle avec la construction C++11 : ce gain peut être appréciable dans le monde de l’embarqué, où la mémoire est une ressource rare.

    Source et exemples de code : Goodbye, Q_FOREACH.
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 393
    Points : 685
    Points
    685
    Par défaut
    (C++17 pour std::as_const. Mais cf cppreference, ce n'est pas compliqué a implémenté en C++11)

Discussions similaires

  1. While et foreach : utilisation foreach sans while et avec while
    Par tonton.odilon dans le forum Langage
    Réponses: 10
    Dernier message: 06/10/2015, 21h24
  2. Réponses: 3
    Dernier message: 02/02/2012, 15h55
  3. [Tableaux] Problème de foreach avec des checkboxes
    Par nanor21 dans le forum Langage
    Réponses: 10
    Dernier message: 15/05/2006, 01h04
  4. [Tableaux] Pb avec array_push et foreach
    Par pounie dans le forum Langage
    Réponses: 4
    Dernier message: 16/12/2005, 17h56
  5. [SimpleXML] XML et parcours des noeuds avec foreach
    Par kult dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 15/11/2005, 15h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo