История изменений
Исправление seiken, (текущая версия) :
На C++ можно создавать новый тип данных, и в его экземплярах хранить состояние. И не парить мозг захватом автоматических переменных и UB. Как-то так:
#include <iostream>
#include <optional>
#include <functional>
template<class T>
using NextF = std::function<T(const T&, const T&)>;
template<class T>
struct Sequencer
{
    Sequencer(NextF<T> nextF_): nextF(nextF_) { }
    T operator()(const T& Y)
    {
        return (X = X.has_value() ? nextF(X.value(), Y) : Y).value();
    }
    NextF<T> nextF;
    std::optional<T> X;
};
template<class T> Sequencer(NextF<T>) -> Sequencer<T>;
int main()
{
    auto multF = std::function(std::multiplies<int>());
    auto seq = Sequencer(multF);
    std::cout << seq(3) << std::endl; // В отличие от Java, никакого бойлерплейта с ".get(...)"
    std::cout << seq(4) << std::endl;
    std::cout << seq(5) << std::endl;
}
Исходная версия seiken, :
На C++ можно создавать новый тип данных, и в его экземплярах хранить состояние. И не парить мозг захватом автоматических переменных и UB. Как-то так:
#include <iostream>
#include <optional>
#include <functional>
template<class T>
using NextF = std::function<T(const T&, const T&)>;
template<class T>
struct Sequencer
{
    Sequencer(NextF<T> nextF_): nextF(nextF_) { }
    T operator()(const T& Y)
    {
        return (X = X.has_value() ? nextF(X.value(), Y) : Y).value();
    }
    NextF<T> nextF;
    std::optional<T> X;
};
template<class T> Sequencer(NextF<T>) -> Sequencer<T>;
int main()
{
    auto multF = std::function(std::multiplies<int>());
    auto seq = Sequencer(multF);
    std::cout << seq(3) << std::endl;
    std::cout << seq(4) << std::endl;
    std::cout << seq(5) << std::endl;
}