Я пишу числовой интегратор как часть библиотеки. Как вы, возможно, знаете, существует довольно много различных типов числовых интеграторов (коты Ньютона, квадратуры Гаусса и т. д.), и я бы хотел, чтобы они были взаимозаменяемыми. Обычно это можно сделать, имея интерфейс для интегратора, а затем несколько конкретных типов, реализующих этот интерфейс. Однако мои интеграторы должны иметь возможность интегрировать функции любых арифметических типов (это одна из причин, почему я пишу это сам), т. е. они должны поддерживать double, но также DoubleDouble и все, что разумно ведет себя как представление вещественного числа. . Поэтому я решил написать интегратор как шаблонный класс, а любые другие функции, которым нужен интегратор, должны быть функциями шаблона, где интегратор будет параметром шаблона. Однако мне бы хотелось, чтобы этот параметр шаблона был ограничен какой-либо концепцией Интегратора.
Минимальный воспроизводимый пример
Код: Выделить всё
#include
#include
#include
#include
template
A
helper(Ret(F::*)(A, Rest...));
template
A
helper(Ret(F::*)(A, Rest...) const);
template
struct GetFirstArgumentOf {
typedef std::remove_cvref_t type;
};
template
using GetReturnTypeOf =
typename decltype(std::function{ std::declval() })::result_type;
template
concept IsFunctionFromR = requires(GetFirstArgumentOf::type argument) {
[](std::array) {}(argument); //checks argument type (TODO should work for copy or const reference)
};
template
concept IsFunctionToR = requires(GetReturnTypeOf return_) {
[](T) {}((T) return_);
};
template
concept IsFunctionFromRN = requires(GetFirstArgumentOf::type argument) {
[](std::array) {}(argument);
};
template
concept IsFunctionFromRToR = IsFunctionFromR && IsFunctionToR;
template
concept IsFunctionFromRNToR = IsFunctionFromRN && IsFunctionToR;
template
class Integrator {
public:
template
requires IsFunctionFromRToR
T Integrate(const F& f, std::array a, std::array b) const {
return (b[0] - a[0]) * (f(a) + f(b)) / 2.0;
}
template
requires IsFunctionFromRNToR && (!IsFunctionFromRToR)
auto Integrate(const F& f, std::array a, std::array b) const {
constexpr int dimension = std::tuple_size::value;
return [=](std::array y) {
auto f_at_y = [&](std::array x) {
std::array argument{0};
argument[0] = x[0];
for(int i = 1; i < dimension; i++) {
argument[i] = y[i - 1];
}
return f(argument);
};
return Integrate(f_at_y, a, b);
};
}
};
int main() {
Integrator i;
auto f = [](std::array x) {
return x[0] + x[1] * x[1];
};
std::array a = { 0 };
std::array b = { 1 };
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79286193/writing-a-c-concept-for-a-class-that-has-a-method-which-takes-an-stdarray-of[/url]