std::adjacent_difference
для именно это, но, как вы упомянули, он копирует первый элемент к результату, который вы не хотите. Использование Boost.Iterator, довольно легко сделать back_inserter, который отбрасывает первый элемент.
#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);
});
}
Тогда вы можете #include <boost/range/numeric.hpp>
и сделать это:
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
Если вы хотите, чтобы ваша двоичная функция возвращает другой тип (например, строка), выше решение не будет работать, потому что, хотя вставка cont.push_back(i)
никогда не называется для первой скопированной eleme nt, он все равно должен быть составлен, и он не пойдет.
Итак, вы можете вместо этого сделать back_inserter, который игнорирует любые элементы другого типа, чем в контейнере. Это игнорирует первый, скопированный элемент и принимает остальные.
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});
}
Тогда вы можете использовать его аналогичным образом.
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 Итераторы и обратные итераторы несовместимы. 'v.end() - 1' и' v.rbegin() 'указывают на один и тот же элемент, но не могут сравниться. – interjay
@interjay Упс. :) – erip
Кажется, здесь было обсуждено без ответа: http://stackoverflow.com/questions/19927563/for-each-that-gives-two-or-n-adjacent-elements Кроме того, я конечно, я видел сообщение в блоге с реализацией, я отправлю его в качестве ответа, если найду его ... –