2 votes

Mapper un itérateur à un itérateur sur un champ spécifique (peut utiliser Boost)

Supposons que je dispose d'un algorithme particulier qui fonctionne sur une plage d'entiers. La fonction prendra alors deux itérateurs sur cette plage et effectuera son travail.

template <typename It>
void doWork(It begin, It end) {
    int x = *begin; // range is over integers
    // ...
}

Supposons que je dispose de deux structures de données :

struct S { int x; }

using TupleList = std::vector<std::tuple<int, double>>;
using SList = std::vector<S>;

J'aimerais utiliser l'algorithme à la fois sur un TupleList et un SList (séparément). Cependant, les itérateurs directs ne fonctionneront pas comme des TupleList y SList ne contiennent pas directement des entiers.

Une solution consisterait à transmettre à l'algorithme un foncteur permettant de décompresser les itérateurs :

template <typename It, typename Unwrap>
void doWork(It begin, It end, Unwrap unwrap) {
    int x = unwrap(*begin);
    // And so on
}
// -----
auto Sunwrapper = [](const S& s) { return s.x; }
doWork(begin(Slist), end(Slist), Sunwrapper);

Mais je préfère que la fonction reste ordonnée. Existe-t-il un moyen en C++ (et Boost) de créer automatiquement un itérateur à partir d'une telle fonction de déballage ?

auto unwrappedBegin = some_magical_factory(begin(Slist), Sunwrapper);
auto unwrappedEnd   = some_magical_factory(end  (Slist), Sunwrapper);

doWork(unwrappedBegin, unwrappedEnd);

2voto

user2079303 Points 4916

boost::transform_iterator semble être un adaptateur approprié. Il suffit de remplacer some_magical_factory con boost::make_transform_iterator Il suffit d'inclure l'en-tête approprié et cela devrait fonctionner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X