[英]C++ functor (mapping)
I have created a class either<l, r>
much like Haskell's Either ab
. 我创建了一个类, either<l, r>
类似于Haskell的Either ab
either<l, r>
。 I have also implemented a function map
directly in the class; 我还直接在该类中实现了功能map
; this is what the code looks like: 代码如下所示:
template<typename l, typename r>
class either
{
template<typename b>
either<l, b> map(const std::function<b (r)> &f)
{
// ...
}
};
Now I want to isolate the map
function in order to create an abstract base class called functor
现在,我想隔离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
would inherit this class: either
都将继承此类:
class either : functor<r, either<l, r>>
however this is invalid C++ as template member functions can not be virtual. 但是,这是无效的C ++,因为模板成员函数不能是虚拟的。
Moreover, I have attempted to test if <r, either<l, r>>
can match <a, derived<a>>
in functor<r, either<l, r>>
(or any other template for that matter) but haven't been able to since it has two template parameters. 而且,我试图测试<r, either<l, r>>
可以与functor<r, either<l, r>>
(或其他任何模板)中的<a, derived<a>>
匹配<a, derived<a>>
但是由于它具有两个模板参数,因此无法实现。 Also note that other derived classes of functor might have different numbers of template arguments that are irrelevant to functor. 还要注意,函子的其他派生类可能具有与函子无关的不同数量的模板参数。
Can the functor base class be expressed in C++ templates? 函子基类可以用C ++模板表示吗?
Since you are using the curiously recurring template pattern, there's no need for virtual functions. 由于您使用的是奇怪的重复发生的模板模式,因此不需要虚拟函数。 Your goal of dispatching to the method of the derived class can be achieved directly from the base class. 您可以直接从基类中实现派生到派生类的方法的目标。
A typical implementation would be the following : 一个典型的实现如下:
#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;
}
I took the liberty of pointing some things out in the comments. 我乐于在评论中指出一些事情。 HTH HTH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.