Как я могу определить концепцию для функторов, которая принимает шаблонные классы в качестве своих параметров?
Я пишу программу для численного моделирования. Одна из моих функций принимает обратные вызовы. Функция реализована как шаблонная функция, а обратные вызовы - как классы шаблонов, поэтому вызовы обратных вызовов могут быть встроенными.
Теперь моя функция усложняется, и я хотел бы объявить сигнатуры обратных вызовов четко определенным, автоматически проверяемым способом. Поэтому я посмотрел на C++ Concepts TS.
И здесь проблема. Я хотел бы определить концепцию функтора, который принимаетstd::array
, например
struct sum {
template <class Float, size_t N>
Float operator()(std::array<Float, N> const& arr) {
// return the sum of arr...
}
};
struct avg {
template <class Float, size_t N>
Float operator()(std::array<Float, N> const& arr) {
// return the average of arr...
}
};
Примечание. Это упрощенный пример. Изменение подписи функторов (например, std::array
для пары итераторов) не является невозможным, но не является предпочтительным.
Как написать концепцию, которая представляет общий интерфейс sum
а также avg
выше?
Сначала я попробовал:
template <class F, class Float, size_t N>
concept bool ArrayProcessor = requires (F func, std::array<Float, N> arr) {
func(arr);
};
Но это приводит (на мой взгляд) к ужасному коду; при определении функции шаблона, которая использует обратные вызовы, ее объявление выглядит так:
template <ArrayProcessor<double, 1> CB, ...>
void simulate(CB const& callback, ...) {
...
}
<double, 1>
part - пустышка, необходимая для прохождения компиляции. Это решение вряд ли приемлемо, потому что аргумент шаблона для callback.operator()
может измениться внутри simulate
; разные типы и размеры std::array
s могут быть переданы ему.
Второй я попробовал:
template <class F>
concept bool ArrayProcessor = requires (F func, auto arr) {
func(arr);
};
Этот код плохо сформирован, потому что он плохо сформирован для использования спецификатора ограниченного типа в выражении require-(ссылка: https://groups.google.com/a/isocpp.org/forum/m/). Кстати, gcc 6.1.0 выдает внутреннюю ошибку компиляции.
Итак, вопрос: как я могу определить концепцию для функторов, которая принимает шаблонные классы в качестве своих параметров (желательно без обходных путей)?
Благодаря моему поиску у меня сложилось впечатление, что C++ Concepts, возможно, не предназначены для таких целей, как это. Предложения по альтернативам C++ Concepts также приветствуются.
(Может быть, связано с указанием концепции для типа, который имеет шаблон функции-члена с использованием Concepts Lite, но я не могу сказать, является ли он дубликатом)