【问题标题】:Derived Functor with any return type and any parameters具有任何返回类型和任何参数的派生函子
【发布时间】:2009-05-05 17:08:55
【问题描述】:

我有一个使用函子作为工作单元的类。它在其 Run() 方法中接受对仿函数的引用。要允许此类对任何函子进行操作,所有这些函子都必须派生自我的基函子类,如下所示:

class baseFunctor{

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

这可行,但显然它将这些函子限制为具有返回 void 且不接受任何参数的运算符方法。我需要能够在我的类中接受一个函子,它可以接受任何类型的参数并返回任何东西。它显然是可行的,但我似乎无法找到一种方法来做到这一点。我曾考虑过使用模板、多重继承,但我一直受到以下事实的阻碍:需要运行此函子的类必须能够接受任何类型,因此将接受基类类型,因此不知道实际类型函子。

任何有关查看途径的建议都将不胜感激。

【问题讨论】:

    标签: c++ templates inheritance functor


    【解决方案1】:

    调用函子的类如何知道要提供哪些参数以及如何处理返回值(如果有)?

    【讨论】:

      【解决方案2】:

      所以,如果我没看错的话,你有一个“访客模式”。向上看可能是件好事。

      某人需要知道函子是什么类型才能给它参数。通常使用函子,参数被分配给派生类的字段,并且 operator() 将对这些字段进行操作。也就是说,调用函子但对它一无所知的愚蠢方法由知识渊博的人给出了闭包(方法加参数都在一个类中)。

      如果您确实想要在 operator() 中接受多个参数的泛型仿函数,那么模板可以帮助您实现这一目标,但您需要每个参数一个。

      【讨论】:

      • 好的,有道理。创建类并将其传递给函子的主类知道函子是什么类型,它接收函子的类不知道函子,并且只调用 operator() 方法。我会研究访问者模式,谢谢你的信息。
      【解决方案3】:

      我同意尼尔的观点。您的主类必须知道要传递哪些参数以及这些函子期望的返回值。您可以将您的“仿函数”类型转换为支持具有必要参数和返回值的函数的适当类吗?

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

      正如 Drew 所指出的,我不确定使用访问者模式无法更容易实现的这种方法可以实现什么。

      【讨论】:

        【解决方案4】:

        如果您愿意使用 Boost 库 (www.boost.org),您可能会发现 Boot.Bind 和 Boost.Function 特别感兴趣。我过去曾使用它们来实现与您所讨论的内容非常相似的目标。

        如果您使用 Boost.Bind,则可以对函子执行柯里化,以解决函子预期的参数数量与 Run 方法预期的参数数量(即零)之间的差异。创建函子的代码必须将任何参数绑定到特定值,从而创建一个可以传递给 Run() 的零参数函子。

        MV

        【讨论】:

          【解决方案5】:

          为什么要返回函子?你也存储一些状态吗?一些更详细的信息将不胜感激,因为不清楚您到底想做什么。

          如果您打算使用继承,请查看协变返回类型(以及 Virtual Constructor idiom)。

          现在,对于问题的实质:问题实际上不在于传递函子,而在于函子应用程序。您可能还想看看boost::lambdaboost::parameter

          【讨论】:

            【解决方案6】:

            我认为您需要省略号参数,例如 C++ 的可变参数。

            【讨论】:

              【解决方案7】:

              也许你对 std::tr1::function 很感兴趣?

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多