Wrap the functions, providing the boilerplate in the wrapper functions:
template<typename Container, typename Transform>
void transform_container(Container & container, Transform transform) {
std::transform(std::begin(container), std::end(container),
std::begin(container), /* requires output iterator */
transform);
}
template<typename T, typename Container>
auto inner_product_self(Container&& container, T initial) {
return std::inner_product(std::begin(container), std::end(container),
std::begin(container),
initial);
}
Your code then becomes:
int main() {
std::vector<int> v(2);
std::itoa(std::begin(v), std::end(v), 0);
transform_container(v, [](auto i) { return i + 2; });
transform_container(v, [](auto i) { return i * 3; });
auto result = inner_product_self(container, 0);
std::cout << "result: " << result;
}
(Live on ideone)
You're not chained to object oriented programming!