J'ai une structure de liste chaînée:Utiliser boost :: iterator_facade <>
struct SomeLinkedList
{
const char* bar;
int lots_of_interesting_stuff_in_here;
DWORD foo;
SomeLinkedList* pNext;
};
Il fait partie d'une API existante et je ne peux pas le changer.
Je voudrais ajouter le support de l'itérateur. La bibliothèque boost::iterator_facade<>
semblait idéale à cet effet.
class SomeIterator
: public boost::iterator_facade< SomeIterator,
const SomeLinkedList,
boost::forward_traversal_tag >
{
public:
SomeIterator() : node_(NULL) {};
explicit SomeIterator(const SomeLinkedList* p) : node_(p) {};
private:
friend class boost::iterator_core_access;
void increment() { node_ = node_->pNext; };
bool equal(SomeIterator const& other) const { /*some comparison*/; };
SomeLinkedList const& dereference() const { return *node_; };
SomeLinkedList const* node_;
}; // class SomeIterator
L'objectif est de pouvoir l'utiliser dans les fonctions de la bibliothèque standard comme std::for_each
void DoSomething(const SomeLinkedList* node);
SomeLinkedList* my_list = CreateLinkedList();
std::for_each(SomeIterator(my_list), SomeIterator(), DoSomething);
Malheureusement, je reçois une erreur disant qu'il essaie de transmettre la liste par valeur plutôt que par pointeur .
error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'
Comment puis-je changer SomeIterator
faire pour obtenir ce travail correctement?
Merci, paulh
Edit: J'ai essayé ceci:
class SomeIterator
: public boost::iterator_facade< SomeIterator,
SomeLinkedList,
boost::forward_traversal_tag,
SomeLinkedList* >
{
// ...
mais je reçois cette erreur de complier:
error C2664: 'boost::implicit_cast' : cannot convert parameter 1 from 'SomeLinkedList **' to 'boost::detail::operator_arrow_proxy<T>
Ed il 2:
J'ai essayé de modifier le type de déréférencement:
class SomeIterator
: public boost::iterator_facade< SomeIterator,
const SomeLinkedList,
boost::forward_traversal_tag >
{
// ...
const SomeLinkedList* dereference() const { return node_; };
mais, je reçois l'erreur d'origine:
error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'
Re: l'édition. Vous dites toujours que 'value_type' va être' SomeLinkedList'. Vous ne devriez probablement pas avoir besoin du dernier paramètre, puisque la valeur par défaut devrait fonctionner pour cela. Aussi, avez-vous changé le type de retour du membre 'dereference'? - Mais encore, puisque votre base de code ne semble pas être particulièrement stdlib-style, ne serait-il pas plus simple d'écrire votre propre foreach pour cette liste liée particulière (puisque je doute que tout autre algorithme stdlib va bien fonctionner avec un tel un itérateur bizarre de toute façon sans travail supplémentaire sérieux)? – UncleBens
@UncleBens - Voir édition 2. En outre, je ne pense pas que ce serait beaucoup de travail supplémentaire. Il suffit de surcharger un opérateur de comparaison ou un prédicat binaire. – PaulH
Il semble que vous ayez besoin de 'const SomeLinkedList *' pour les paramètres 'value_type' et' reference'. Probablement un peu bizarre quand il s'agit de prendre des références à des pointeurs. - Quant au travail supplémentaire: vous convient. Pour moi, l'utilisation de chaînes de style C avec stdlib est trop de travail, car il n'a jamais été conçu pour supporter ceux qui sortent de la boîte. – UncleBens