4 Réponses :
Votre Queue_inserter Code> doit être dérivé de std :: itérateur code> de sorte que tous les caractères de caractères tels que valeur_type code> sont correctement définis car ceux-ci sont utilisés. Aux algorithmes STL, cette définition fonctionne: template< typename T, typename U >
class queue_inserter : public std::iterator<std::output_iterator_tag, T>{
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q) { }
queue_inserter<T,U> operator ++ (int) { return *this; }
queue_inserter<T,U> operator ++ () { return *this; }
queue_inserter<T,U> operator * () { return *this; }
void operator = (const T &val) { qu.push(val); }
};
C'est incroyable à quel point la STL a été mal conçue. Je pensais que tout le point d'itérateurs était-ce que je pouvais rouler le mien? Est-ce que Char * code> hérit de std :: itérateur? Mais merci pour l'info. :-)
Vous pouvez toujours me contenter de ne pas dériver .. (Je ne l'ai pas essayé cependant), mais vous avez besoin de tous ces Typefs vous-même.
@Frank Krueger: Comment concevriez-vous les algorithmes de la bibliothèque standard pour travailler efficacement s'ils ne peuvent pas déterminer les propriétés des types dont ils ont besoin pour fonctionner? Ce n'est pas un problème trivial. STD :: Itérator_Traits est spécialisé par la mise en œuvre des types de pointeur afin que ceux-ci puissent être utilisés avec des algorithmes sans autre travail de la part de l'utilisateur.
En réalité, le type d'itérateur doit être std :: Sortie_Put_iterator_tag code>, Bidirectionnel implique que opérateur - () code> est défini.
@FRANK: C'est un commentaire médiocre. La manière dont les itérateurs sont conçus est une technique très courante utilisée en C ++ pour passer des informations de type sur le type lors de l'utilisation de modèles. Faites juste une recherche sur des traits de Quicj et je suis sûr que vous trouvez des articles appropriés dessus. Remarque: les algorithmes utilisent des traits. Pour les types de pointeur (comme Char *), ils sont explicitement définis pour les objets de classe qu'ils rapprochent au type pour les informations requises. Toutes les choses très basiques.
Mais sont Typefs B> héritées de cette façon? Je suis confus entre cette réponse et une autre réponse ( Lien ).
Fyi @hindol, héritant de std :: itérateur code> i> donnera à votre enfant la classe de ces membres Typefs. (link) dit que Même si l'enfant a i> ces Typefefs, l'enfant ne peut pas réellement les utiliser en interne elle-même i> (par exemple, pour déclarer opérateur de référence * () const code>) ; C'est uniquement parce que l'enfant est un modèle i>. Les TypeDEFS sont dans un sens "uniquement visible pour les étrangers", à moins que l'enfant ne saute par des cerceaux pour y accéder lui-même.
Dérivez-le de STD :: Itérateur. Si vous êtes intéressé, le Dr Dobb's a un article sur des conteneurs personnalisés et des itérateurs. P>
Votre itérateur ne répond pas à l'exigence d'un type "assignable" qui est une exigence d'un itérateur de sortie car il contient une référence et des types assignables doivent s'assurer qu'après Vous pouvez fournir une spécialisation appropriée pour t = u code> que < code> t code> est équivalent à u code>. itérator_traits code> pour votre itérateur soit en dérivant d'une spécialisation de std :: itérateur code> ou en fournissant une explicitement. p>
Merci de me donner la curiosité d'en savoir plus sur itérator_traits code>! Jamais le savait avant. Bien qu'une spécialisation explicite de itérator_traits code> n'est pas nécessaire. Voir ma réponse :)
itérator_traits code>, char_traits code>, pointeur_traits; code>, regex_traits code> et allocator_traits code> aussi! Il y a aussi un
#include <queue>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
template< typename T, typename U >
class queue_inserter
{
queue<T, U> &qu;
public:
// for iterator_traits to refer
typedef output_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
queue_inserter(queue<T,U> &q) : qu(q) { }
queue_inserter<T,U>& operator ++ () { return *this; }
queue_inserter<T,U> operator * () { return *this; }
void operator = (const T &val) { qu.push(val); }
};
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
{
return queue_inserter<T,U>(q);
}
int main()
{
// uses initalizer list (C++0x), pass -std=c++0x to g++
vector<int> v({1, 2, 3});
queue<int, deque<int>> q;
copy(v.cbegin(), v.cend(), make_queue_inserter(q));
while (!q.empty())
{
cout << q.front() << endl;
q.pop();
}
}
This should do it with iterator_traits; a helper struct in <iterator> which defines all types an iterator should typically define. Functions in <algorithm>, refer to these types when required like iterator_traits<it>::iterator_category or say iterator_traits<it>::value_type, etc. Just defining them inside one's custom iterator would do the trick. This is the modern way of writing iterators, as opposed to the classical way of inheriting from std::iterator. Having a look at <iterator> reveals that even std::iterator defines these types i.e. iterator_category, difference_type, etc. This is the reason, when inherited from std::iterator, the derived iterator class gets these due to heredity.
Pourquoi hériter de std :: itérateur code> obsolète et où je peux en trouver plus sur la façon de faire la bonne façon alors?
S'il vous plaît voir Cette réponse pour plus de détails. Et désolé pour la réponse très tardive, je ne savais pas que vous auriez demandé.
Et comment l'algorithme devrait-il savoir ce que type i> d'itérateur est? Par exemple, l'algorithme peut être plus rapide avec des itérateurs d'accès aléatoire, mais comment savoir si votre itérateur est un accès aléatoire ou non?
Parce que tous vos itérateurs devraient commencer comme ça
struct file_inserter: boost :: iterator_facade <...> {... code>@ALFC: FWIW, je viens d'essayer d'écrire un médicament simple avec
boost :: iterator_facade code> et a immédiatement eu des ennuis. Stackoverflow.com/questions/43481025 Depuis que l'OP était aussi i> essayer de créer un médicamentiterator "itérator_facade code> résout tous vos problèmes de magie "n'est pas un conseil utile. Se passe,itérator_facade code> crée i> des problèmes à part entière. (Devrait toujours l'utiliser, mais ce n'est pas une réponse à une ligne. C'est une réponse multiligne avec plusieurs mises en garde et, espérons-le, un exemple.)@Queuxplusone. Oui, le commentaire est un indice, pas une réponse.