LINUX.ORG.RU

История изменений

Исправление 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;
}
Наверняка можно и более грамотный вариант сделать, но этот тоже рабочий.