我知道在虚方法上使用模板是不可能的,因为编译没有办法知道如何实现所有可能性,但我需要的是在限制的方式上使用模板,如:
template<typename T, size_t N>
class MatBase {
public:
static constexpr size_t order = N;
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
template<class Fn = T(T)>
virtual void Map(Fn&& fn) = 0;
template<class Fn = T(T,T)>
virtual T Reduce(Fn&& fn) = 0;
};
这意味着,Fn使用在类上声明的模板,所以我认为编译器可以推断出所有可能的类型。有没有办法做类似C ++的东西?
答案 0 :(得分:4)
如你所说,你不能拥有模板化虚拟功能。但是,为什么你需要模板呢?请参阅以下示例代码。
#include <cstddef>
template<typename T, size_t N>
class MatBase
{
public:
static constexpr size_t order = N;
using MapFn = T (*)(T);
using ReduceFn = T (*)(T, T);
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
virtual void Map(MapFn&& fn) {}
virtual T Reduce(ReduceFn&& fn) {}
};
int main()
{
MatBase<int, 3> m;
return 0;
}
更灵活的解决方案可能会考虑使用std::function
(例如std::function<T (T)>
)作为参数,因为它为调用者提供了更大的灵活性。例如,调用者可以使用普通函数,成员函数,lambda表达式或函子对象。
答案 1 :(得分:1)
另一个答案适用于普通的,花园式的,功能指针。但是,使用一些类型擦除或其一些改编也应该可以使用实现合适的operator()
成员的类的实例。
我会为Map()
写出来。对Reduce()
重复相同的方法是类似的,并且将是一项家庭作业:
#include <cstddef>
template<typename T, size_t N>
class MatBase
{
public:
static constexpr size_t order = N;
using value_type = T;
MatBase() = default;
virtual ~MatBase() = default;
template<typename Arg> void Map(Arg && arg)
{
std::function< value_type(value_type> > f=
[&]
(value_type value)
{
return arg(value);
};
do_map(f);
}
virtual void do_map(std::function< value_type(value_type) > &)=0;
};