0

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

class baseFunctor{

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

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

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

4

7 回答 7

2

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

于 2009-05-05T17:23:06.623 回答
1

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

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

如果您确实想要在 operator() 中接受多个参数的泛型仿函数,那么模板将使您成功,但您需要每个参数一个。

于 2009-05-05T17:42:43.567 回答
1

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

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

MV

于 2009-05-05T17:22:11.993 回答
1

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

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 所指出的,我不确定使用访问者模式无法更容易实现的这种方法可以实现什么。

于 2009-05-05T18:05:14.603 回答
0

也许 std::tr1::function 对您来说很有趣?

于 2009-05-05T17:27:17.613 回答
0

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

如果您打算使用继承,请查看 Covariant Return Types(和Virtual Constructor idiom)。

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

于 2009-05-05T17:20:05.930 回答
0

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

于 2009-05-05T17:21:38.110 回答