如何在虚方法上使用模板参数类?

时间:2016-04-30 18:52:28

标签: c++ oop templates c++11

我知道在虚方法上使用模板是不可能的,因为编译没有办法知道如何实现所有可能性,但我需要的是在限制的方式上使用模板,如:

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 ++的东西?

2 个答案:

答案 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;
}

Live Example

更灵活的解决方案可能会考虑使用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;
};