std::adjacent_difference
è proprio per questo, ma come lei ha ricordato, copia il primo elemento al risultato, che non si vuole. Utilizzando Boost.Iterator, è abbastanza facile creare un back_inserter che getta via il primo elemento.
#include <boost/function_output_iterator.hpp>
template <class Container>
auto mybackinsrtr(Container& cont) {
// Throw away the first element
return boost::make_function_output_iterator(
[&cont](auto i) -> void {
static bool first = true;
if (first)
first = false;
else
cont.push_back(i);
});
}
Poi si può #include <boost/range/numeric.hpp>
e fare questo:
std::vector<int> v { 0, 1, 2, 3 }; // any generic STL container
std::vector<int> result;
boost::adjacent_difference(v, mybackinsrtr(result), std::plus<>{}); // any binary function
See it on ideone
Quando si desidera la funzione binaria per restituire un tipo diverso (ad esempio una stringa), quanto sopra soluzione non funzionerà perché, anche se l'inserimento cont.push_back(i)
non è mai chiamato per il primo eleme copiato nt, deve essere ancora compilato e non funzionerà.
Quindi, è possibile creare un back_inserter che ignora qualsiasi elemento di un tipo diverso da quello nel contenitore. Questo ignorerà il primo, copiato, elemento, e accetterà il resto.
template <class Container>
struct ignore_insert {
// Ignore any insertions that don't match container's type
Container& cont;
ignore_insert(Container& c) : cont(c) {}
void operator() (typename Container::value_type i) {
cont.push_back(i);
}
template <typename T>
void operator() (T) {}
};
template <class Container>
auto ignoreinsrtr(Container& cont) {
return boost::make_function_output_iterator(ignore_insert<Container>{cont});
}
Quindi è possibile utilizzarlo in modo simile.
std::vector<int> v { 0, 1, 2, 3 }; // any generic STL container
std::vector<std::string> result;
boost::adjacent_difference(v, ignoreinsrtr(result), [](int a, int b){ return std::to_string(a+b); });
On ideone
@erip Iteratori e iteratori inversi non sono tipi compatibili. 'v.end() - 1' e' v.rbegin() 'puntano allo stesso elemento, ma non possono essere confrontati. – interjay
@interjay Whoops. :) – erip
Sembra che una discussione senza risposta sia già stata presentata qui: http://stackoverflow.com/questions/19927563/for-each-that-gives-two-or-nadadacent-elements Inoltre, sono sicuro di aver visto un post sul blog con un'implementazione, lo posterò come risposta se riesco a trovarlo ... –