我正在编写一个数值模拟程序。我的一个函数需要回调。该函数作为模板函数实现,并作为模板类进行回调,因此可以内联对回调的调用。
现在,我的功能变得越来越复杂了,我想以一种明确定义的,可自动检查的方式声明回调的签名。所以我查看了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>
部分是编译通过所需的虚拟部分。此解决方案几乎不可接受,因为callback.operator()
的模板参数可能会在simulate
内发生变化; std::array
的不同类型和大小可以传递给它。
第二次我试过了:
template <class F>
concept bool ArrayProcessor = requires (F func, auto arr) {
func(arr);
};
这段代码格式不正确,因为在requires-expression中使用约束类型说明符是不正确的(参考:https://groups.google.com/a/isocpp.org/forum/m/#!topic/concepts/_gHn0wJJNGA)。顺便说一下,gcc 6.1.0会对它产生内部编译错误。
所以,问题是:我如何定义一个以模板类作为参数的仿函数的概念(最好没有解决方法)?
通过我的搜索,我得到的印象是C ++ Concepts可能不适合这样的用途。对C ++概念的替代方案的建议也非常受欢迎。
(可能与Specifying a concept for a type that has a member function template using Concepts Lite有关,但我不知道它是否重复)