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) 从未调用复制的元素,它仍然必须编译,它不会去。
因此,您可以改为创建一个 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