I'm writing a program for numerical simulations. One of my functions takes callbacks. The function is implemented as a template function and callbacks as template classes, so that calls to the callbacks may be inlined.
Now, my function is getting complicated, and I'd like to declare the signatures of callbacks in a well-defined, auto-checkable way. So I looked to C++ Concepts TS.
And here is the problem. I'd like to define a concept of a functor that takes anstd::array
, for example
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...
}
};
Note: This is a simplified example. Changing the signature of functors (e.g. std::array
to a pair of iterators) is not impossible but not preferred.
How to write a concept that represents the common interface of sum
and avg
above?
First I tried:
template <class F, class Float, size_t N>
concept bool ArrayProcessor = requires (F func, std::array<Float, N> arr) {
func(arr);
};
But this lead to (in my opinion) an ugly code; at the definition of the template function that uses the callbacks, its declaration looks like this:
template <ArrayProcessor<double, 1> CB, ...>
void simulate(CB const& callback, ...) {
...
}
The <double, 1>
part is a dummy required for the compilation to pass. This solution is hardly acceptable because the template argument for callback.operator()
may change inside simulate
; different types and sizes of std::array
s may be passed to it.
Second I tried:
template <class F>
concept bool ArrayProcessor = requires (F func, auto arr) {
func(arr);
};
This code is ill-formed because it's ill-formed to use constrained-type-specifier in requires-expression (reference: https://groups.google.com/a/isocpp.org/forum/m/#!topic/concepts/_gHn0wJJNGA). By the way gcc 6.1.0 produces an internal compilation error against it.
So, the question is: How can I define a concept for functors that takes template classes as their parameters (preferrably without workarounds)?
Through my searching, I got the impression that C++ Concepts may not be designed for uses like this. Suggestions to alternatives to C++ Concepts are greatly appreciated as well.
(Maybe related to Specifying a concept for a type that has a member function template using Concepts Lite but I can't tell if it's duplicate)