我创建了一个类 either<l, r>
很像 Haskell 的 Either a b
.我还实现了一个函数 map
直接在类里面;这是代码的样子:
template<typename l, typename r>
class either
{
template<typename b>
either<l, b> map(const std::function<b (r)> &f)
{
// ...
}
};
现在我想隔离 map
函数以创建一个名为 functor
的抽象基类
template<typename a, template <a> class derived>
class functor
{
public:
virtual ~functor();
template<typename b>
derived<b> map(const std::function<b (a)> &f) = nullptr;
};
either
将继承此类:
class either : functor<r, either<l, r>>
但是这是无效的 C++,因为模板成员函数不能是虚拟的。
此外,我试图测试 <r, either<l, r>>
可以匹配 <a, derived<a>>
在functor<r, either<l, r>>
(或与此相关的任何其他模板)但由于它有两个模板参数而无法做到。另请注意,仿函数的其他派生类可能具有不同数量的与仿函数无关的模板参数。
仿函数基类可以用C++模板表达吗?
最佳答案
由于您正在使用奇怪的重复模板模式,因此不需要虚函数。 派生类方法的目标可以直接从基类实现。
一个典型的implementation将是以下内容:
#include <iostream>
#include <functional>
using namespace std;
template<typename a, class derived>
class functor
{
public:
// You have to define the destructor
virtual ~functor() {}
template<typename b>
// The full type of the derived class is known
derived map(const std::function<b(a)> &f)
{
// Here you take advantage of the CRTP
return static_cast<derived*>(this)->map(f);
}
};
template<typename l, typename r>
// You have to put public as inheritance access level
class either : public functor<r, either<l, r>>
{ // The way you want to inherit implies that the base has no
// template template parameter, just template parameters !!
public:
template<typename b>
either<l, b> map(const std::function<b(r)> &f)
{
cout << "In derived" << endl;
return either<l, b>();
}
};
int main()
{
// pointer to base class points to a derived object
functor<int, either<int, int>> *ff = new either<int, int>();
// map function will call the method of the derived class
ff->map<int>([](int k){ return 1; });
return 0;
}
我冒昧地在评论中指出了一些事情。
关于C++ 仿函数(映射),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24874661/