Хранение в функции класса с шаблонной арностью - PullRequest
1 голос
/ 13 июня 2019

Я хочу иметь класс, который представляет дискретную функцию над целыми числами. Арность функции является параметром шаблона. Конструктор должен принимать (указатели на?) Функции этой арности. Я также хотел бы иметь возможность передавать лямбда-выражения в конструктор. Фактически это основной тип функций, которые я буду передавать.

Далее, я хочу иметь метод eval() для вычисления значения функции для предоставленных аргументов.

Вопрос в том, как передать и сохранить функцию, а также как ее оценить.

template<int arity>
class DiscreteFun {
private:
    FuncType f; // what should FuncType be?
public:
    DiscreteFun(FuncType f): f(f) { };

    int eval(const array<int,arity>& x) const {
      // how to pass arguments so that it calculates f(x[0], x[1], ...)
    }
};

Ответы [ 2 ]

3 голосов
/ 13 июня 2019

Вы можете добавить параметр шаблона для типа f, и тогда eval будет просто std::apply. Обратите внимание, что std::array является контейнером, похожим на кортеж.

template<int arity, typename FuncType>
class DiscreteFun {
private:
    FuncType f;
public:
    DiscreteFun(FuncType f): f(f) { };

    int eval(const array<int,arity>& x) const {
        return std::apply(f, x);
    }
};

template<int arity, typename FuncType>
DiscreteFun<arity, FuncType> makeDiscreteFun(FuncType&& f)
{
    return { std::forward<FuncType>(f) };
}
2 голосов
/ 13 июня 2019

Вы можете использовать std::index_sequence и некоторые косвенные ссылки:

template <std::size_t, typename T>
using always_t = T;

template <typename Seq> class DiscreteFunImpl;

template <std::size_t ... Is>
class DiscreteFunImpl<std::index_sequence<Is...>>
{
private:
    std::function<int (always_t<Is, int>...)> f;
public:
    DiscreteFunImpl(std::function<int (always_t<Is, int>...)> f): f(f) {}

    int eval(const array<int, sizeof...(Is)>& x) const {
        return f(x[Is]...);
    }
};


template <std::size_t N>
using DiscreteFun = DiscreteFunImpl<std::make_index_sequence<N>>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...