Question

Étant donné un approprié foncteur pour une utilisation avec std::for_each et amis:

template <typename T> struct Foo {
    void operator()(T const& t) { ... }
};

std::for_each(v.begin(), v.end(), Foo<Bar>());

est-il un moyen standard pour convertir en un itérateur de sortie appropriée pour une utilisation avec std::copy et amis? (Ou l'adaptation opposée) quelque chose comme:

std::copy(v.begin(), v.end(), functor_output_iterator(Foo<Bar>()));

Ce qui appellerait foncteur chaque fois qu'une valeur est affectée à la iterator:

adapter(F f) : functor(f) { }
adapter& operator*()  { return *this; }
operator=(T const& t) { functor(t); }
operator++()          { }
...

Ou bien:

std::for_each(..., some_adapter(std::ostream_iterator(std::cout)));

Arrière-plan:

J'ai une classe qui expose une collection à l'aide d'un itérateur de sortie:

template <typename It> GetItems(It out) {
    MutexGuard guard(mutex);
    std::copy(items.begin(), items.end(), out);
}

Cela permet aux appelants d'avoir accès aux éléments sans les forcer à utiliser un type de conteneur spécifique et sans déconner avec verrouillage ou d'autres détails internes.

par exemple, pour obtenir seulement des objets uniques.

std::set<whatever> set;
obj->GetItems(std::inserter(set, set.end()));

Il bat l'enfer sur:

ObjLock lock = obj->GetLock();
for (int i = 0; i < obj->GetItemCount(); ++i) {
    Item* item = obj->GetItem(i);
    ...

Maintenant, je veux également être en mesure d'agréger ces éléments, plutôt que de les copier. (Voir cette question ). Où je normalement faire quelque chose comme:

std::for_each(v.begin(), v.end(), Joiner<Foo>());

Maintenant, je pourrais faire deux méthodes distinctes pour les mêmes éléments de données, qui appelle std::copy et qui appelle std::for_each mais il serait agréable d'être en mesure de définir simplement une de ces méthodes, en utilisant un itérateur ou un foncteur, et ont des appelants être en mesure de passer soit foncteurs ou itérateurs à elle, en les adaptant au besoin le type approprié.

Ce que je fais est maintenant définir l'aggrégateur de telle sorte qu'il peut être utilisé comme un itérateur de sortie ou un foncteur, mais cela conduit à la complexité indésirable.

Était-ce utile?

La solution

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top