Производный функтор с любым возвращаемым типом и любыми параметрами

StackOverflow https://stackoverflow.com/questions/825935

Вопрос

У меня есть класс, который использует функторы как единицы работы.Он принимает ссылку на функтор в своем методе Run().Чтобы позволить этому классу работать с любым функтором, все эти функторы должны быть производными от моего базового класса функторов, который выглядит следующим образом:

class baseFunctor{

public:
    virtual void operator()()=0;
    virtual baseFunctor Clone()=0;
};

Это работает, однако очевидно, что это ограничивает эти функторы наличием операторного метода, который возвращает void и не принимает никаких параметров.Мне нужно иметь возможность принимать функтор в моем классе, который может принимать параметры любого типа и возвращать что угодно.Это, по-видимому, выполнимо, но, похоже, я не могу найти способ сделать это.Я рассматривал возможность использования шаблонов, множественного наследования, но мне продолжает мешать тот факт, что класс, которому необходимо запустить этот функтор, должен быть способен принимать любой тип, поэтому примет тип базового класса и, следовательно, не будет знать фактический тип функтора.

Будем признательны за любые предложения о том, на какой проспект обратить внимание.

Это было полезно?

Решение

Как класс, вызывающий функтор, узнает, какие параметры предоставить и что делать с возвращаемым значением, если оно есть?

Другие советы

Итак, если я правильно понял, у вас есть "Шаблон посетителя". Это может быть хорошо для вас, чтобы посмотреть вверх.

Кто-то должен знать, к какому типу относится функтор, чтобы передать ему аргументы. Часто с функторами аргументы присваиваются полям производного класса, и оператор () будет работать с этими полями. То есть, тупой метод, который вызывает функтор и ничего о нем не знает, получает закрытие (метод плюс аргументы в одном классе) от кого-то более осведомленного.

Если вам нужны универсальные функторы, которые принимают несколько аргументов в операторе (), шаблонирование приведет вас туда-сюда, но вам понадобится по одному на арность.

Я согласен с Нилом. Ваш основной класс должен знать, какие параметры передавать и какое возвращаемое значение ожидать от этих функторов. Можете ли вы просто набрать свой " функтор " в соответствующий класс, который поддерживает функцию с необходимыми аргументами и возвращаемым значением?

class baseFunctor
{
};

class functor1x2: public baseFunctor
{
public:
    virtual void* execute(void*, void*);

}

class MainClass
{
public:
   void Execute(baseFunctor* ipFunctor)
   {
      functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
      if(lpFunctor1x2)
      {
         lpFunctor1x2->execute(NULL, NULL);
      }
   }
}

Я не уверен, что может быть достигнуто с помощью этого подхода, который не может быть легче реализован с помощью шаблона Visitor, как заметил Дрю.

Если вы готовы использовать библиотеку Boost (www.boost.org), вы можете найти функции Boot.Bind и Boost., представляющие особый интерес.Я использовал их в прошлом, чтобы достичь чего-то очень похожего на то, что вы обсуждаете.

Если вы используете Boost.Bind, вы можете выполнить каррирование функторов, чтобы учесть различия между количеством ожидаемых функтором аргументов и количеством ожидаемых методом Run аргументов (т. е. нулем).Код, создающий функтор, должен был бы привязать любые аргументы к определенным значениям и, таким образом, создать функтор с нулевым аргументом, который может быть передан в Run().

МВ

Почему ты хотел вернуть функтор? Вы тоже храните какое-то государство? Будем весьма благодарны за некоторые подробности, так как не очень понятно, что именно вы хотите делать.

Если вы планируете использовать наследование, поищите Covariant Return Types (и идиома виртуального конструктора ).

Теперь по сути проблемы: проблема на самом деле не в передаче функтора, а в применении функтора. Возможно, вы захотите взглянуть на boost :: лямбда и boost :: parameter .

Я думаю, вам нужен аргумент с многоточием, например, varargs для C ++.

Возможно, функция std :: tr1 :: вам интересна?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top