Параметр шаблона, обозначающий «что-то вызываемое с определенной подписью» - PullRequest
0 голосов
/ 02 мая 2018

Я хотел написать код, подобный этому:

SplineFunction<Polynomial<3>> cubicSplineFunction;
// ... here be some additional code to populate the above object ...

auto dydx = cubicSplineFunction.transform<Polynomial<2>>(const Polynomial<3>& cubicSpline){
    return cubicSpline.derivative();
};

auto dsdx = cubicSplineFunction.transform<T/*?*/>([](const Polynomial<3>& cubicSpline){
    Polynomial<2> dy = cubicSpline.derivative();
    Polynomial<4> dsSquared = dy*dy + 1*1;
    return [dsSquared](double x){ // Fixed in response to comment: capture by value
        return std::sqrt(dsSquared);
    };
});

dydx(1.0); // efficient evaluation of cubicSplineFunction's derivative
dsdx(2.0); // efficient evaluation of cubicSplineFunction's arc rate

Итак, я реализовал классы ниже. Но какой тип я должен заменить на T (в строке 8) выше, чтобы обозначить «что-то вызываемое с подписью double(double)»?

template<typename S>
struct SplineFunction {

    std::vector<S> splines;

    auto operator()(double t) const {
        int i = static_cast<int>(t);
        return splines[i](t - i);
    }

    template<typename R, typename F>
    SplineFunction <R> transform(F f) const {
        SplineFunction <R> tfs;
        for (const auto& s : splines) {
            tfs.splines.push_back(f(s));
        }
        return tfs;
    }

    // ... MORE CODE ...
}

template<int N>
struct Polynomial {
    std::array<double, N+1> coeffs;
    double operator()(double x) const;
    Polynomial<N - 1> derivative() const;

    // ... MORE CODE ...
}

template<int L, int M>
Polynomial<L+M> operator*(const Polynomial<L>& lhs, const Polynomial<M>& rhs);

template<int L>
Polynomial<L> operator+(Polynomial<L> lhs, double rhs);

// ... MORE CODE ...

1 Ответ

0 голосов
/ 02 мая 2018
template<class F, class R=std::result_of_t<F&(S const&)>>
SplineFunction<R> transform(F f) const

не передавайте типы явным образом; пусть они будут выведены.

In do typename std::result_of<F&(S const&)>::type.

Распад R-типа (как в std-распаде) также может быть разумным, поскольку SplineFunction хранит свой параметр шаблона, а затухание делает типы более подходящими для хранения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...