Étant donné un foncteur approprié pour être utilisé avec std::for_each
et ses amis :
template struct Foo {
void operator()(T const& t) { ... }
};
std::for_each(v.begin(), v.end(), Foo());
Existe-t-il un moyen standard de convertir ceci en un itérateur de sortie approprié pour être utilisé avec std::copy
et ses amis? (ou l'adaptation inverse) Quelque chose comme :
std::copy(v.begin(), v.end(), itérateur_sortie_foncteur(Foo()));
Qui appellerait le foncteur à chaque fois qu'une valeur est assignée à l'itérateur :
adaptateur(F f) : foncteur(f) { }
adaptateur& operator*() { return *this; }
operator=(T const& t) { foncteur(t); }
operator++() { }
...
Ou, en alternative :
std::for_each(..., some_adapter(std::ostream_iterator(std::cout)));
Contexte :
J'ai une classe qui expose une collection en utilisant un itérateur de sortie :
template GetItems(It out) {
MutexGuard guard(mutex);
std::copy(items.begin(), items.end(), out);
}
Cela permet aux appelants d'accéder aux éléments sans les forcer à utiliser un type de conteneur spécifique et sans se mêler de verrouillage ou d'autres détails internes.
Par exemple, pour obtenir uniquement des éléments uniques :
std::set set;
obj->GetItems(std::inserter(set, set.end()));
C'est bien mieux que :
ObjLock lock = obj->GetLock();
for (int i = 0; i < obj->GetItemCount(); ++i) {
Item* item = obj->GetItem(i);
...
Maintenant, je veux aussi être capable d'agréger ces éléments, plutôt que de les copier. (Voir cette question). Là où je ferais normalement quelque chose comme :
std::for_each(v.begin(), v.end(), Joiner());
Maintenant, je pourrais créer deux méthodes séparées pour les mêmes éléments de données, une qui appelle std::copy
et une qui appelle std::for_each
mais ce serait bien de pouvoir définir juste une seule telle méthode, en utilisant un itérateur ou un foncteur, et permettre aux appelants de passer soit des foncteurs soit des itérateurs, en les adaptant au type approprié si nécessaire.
Actuellement, je définis l'agrégateur de sorte qu'il puisse être utilisé comme un itérateur de sortie ou un foncteur, mais cela entraîne une complexité non désirée.