типы — функтор C ++ (отображение)

Я создал класс either<l, r> так же, как у Хаскелла 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 ++?

1

Решение

Поскольку вы используете необычно повторяющийся шаблон, вам не нужны виртуальные функции. Ваша цель диспетчеризация в метод производного класса может быть достигнуто непосредственно из базового класса.

Типичный реализация будет следующим:

#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;
}

Я позволил себе указать некоторые вещи в комментариях. НТН

2

Другие решения