如何为将模板类作为参数的仿函数定义一个概念?

时间:2016-08-06 08:46:03

标签: c++ templates c++-concepts

我正在编写一个数值模拟程序。我的一个函数需要回调。该函数作为模板函数实现,并作为模板类进行回调,因此可以内联对回调的调用。

现在,我的功能变得越来越复杂了,我想以一种明确定义的,可自动检查的方式声明回调的签名。所以我查看了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)更改为一对迭代器并非不可能,但不是首选。

如何编写代表上述sumavg的通用界面的概念?

首先我尝试了:

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有关,但我不知道它是否重复)

0 个答案:

没有答案