web-dev-qa-db-fra.com

Pourquoi std :: iterator est-il déconseillé?

Classe de modèle std::iterator est défini comme obsolète en C++ 17. Pourquoi C'est un moyen pratique de s'assurer que std::iterator_traits fonctionne, surtout si vous pouvez utiliser les arguments de modèle par défaut. Existe-t-il une autre façon de le faire en C++ 17?

37
aschepler

De la proposition qui a suggéré sa dépréciation :

Pour faciliter l'écriture des classes d'itérateur, la bibliothèque standard d'origine a fourni le modèle de classe d'itérateur pour automatiser la déclaration des cinq types de caractères attendus de chaque itérateur par iterator_traits. Cela a ensuite été utilisé dans la bibliothèque elle-même, par exemple dans la spécification de std::ostream_iterator:

template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator:
  public iterator<output_iterator_tag, void, void, void, void>;

La longue séquence d'arguments void est beaucoup moins claire pour le lecteur que de simplement fournir les typedefs attendus dans la définition de classe elle-même, qui est l'approche adoptée par le brouillon de travail actuel, suivant le modèle défini en C++ 14 où nous avons déconseillé la dérivation à travers la bibliothèque de foncteurs de unary_function et binary_function.

En plus de la clarté réduite, le modèle d'itérateur pose également un piège pour les imprudents, car dans l'utilisation typique, ce sera une classe de base dépendante, ce qui signifie qu'il ne cherchera pas pendant la recherche de nom à partir de la classe ou de ses fonctions membres. Cela conduit les utilisateurs surpris à essayer de comprendre pourquoi l'utilisation simple suivante ne fonctionne pas:

#include <iterator>

template <typename T>
struct MyIterator : std::iterator<std::random_access_iterator_tag, T> {
   value_type data;  // Error: value_type is not found by name lookup 

   // ... implementations details elided ...
};

La raison de la clarté à elle seule était suffisante pour persuader le LWG de mettre à jour la spécification de bibliothèque standard pour ne plus obliger les adaptateurs d'itérateur standard comme dérivant de std::iterator, il n'y a donc plus d'utilisation de ce modèle dans la norme elle-même. Par conséquent, cela ressemble à un candidat fort pour la dépréciation.

Vous pouvez également voir le raisonnement de STL dans LWG 2438 . (h/t T.C. )


Quant à une autre façon de faire, pas vraiment. Vous pouvez essentiellement implémenter votre propre version de std::iterator (ce qui n'est pas trop difficile) ou écrivez manuellement tous ces caractères (ce qui n'est pas trop difficile non plus, et je le préfère en fait pour plus de clarté).

26
Barry