繁体   English   中英

如何为具有不同签名的功能分配相同的签名?

[英]How to assign same signature to functions with different signatures?

在我的C ++应用程序中,我有2个线程:(i)主线程,(ii)后台线程。 我有一个类定义为:

class helper
{
 public:
     bool login(const string& username, const string& password);
     void logout();

 private:
     bool loginInternal(const string& username, const string& password);
     void logoutInternal();
}

在主线程上调用了helper :: login()和helper :: logout()函数(以及其他几种具有各种返回类型以及#和param和param类型的成员函数)。 在这些函数的实现中,将相应的内部函数放入队列中,并且后台线程按将其排入队列的顺序调用这些内部函数。 所以像这样:

bool helper::login(const string& username, const string& password)
{
    queue.push_back(boost::bind(&helper::loginInternal, this, username, password));
}

void helper::logout()
{
    queue.push_back(boost::bind(&helper::logoutInternal, this));
}

一直以来,后台线程都在运行,等待队列填满,并且一旦这样做,后台线程就会开始调用队列中的函数:

queue.front()();
queue.pop_front();

所以问题是,如何定义这样的队列?

deque<???> queue;

该队列的数据类型可能是什么,以便它可以在同一队列中保存具有不同签名的回调函数?

编辑:这是解决方案(感谢J. Calleja):

typedef boost::function<void ()> Command;
deque<Command> queue;

然后像这样调用函子:

// Execute the command at the front
Command cmd = queue.front();
cmd();

// remove the executed command from the queue
queue.pop_front();

如果您对返回类型进行规范化或忽略它,则可以使用boost :: function 该库定义了一个包装器,该包装器可以存储与您的签名(函数或函子)匹配的任何元素。

使用您的示例:

#include <boost/function.hpp>

class helper 
{  
public:      
  bool login(const std::string& username, const std::string& password);
  void logout();
private:      
  bool loginInternal(const std::string& username, const std::string& password);
  void logoutInternal();
private:
  typedef boost::function<void ()> Command;
  std::deque<Command> queue;
};

此示例忽略返回类型,因为它声明函数返回void。 如果您想知道返回值,则必须使注销返回布尔值并将声明更改为:

  typedef boost::function<bool ()> Command;

我相信第一个的类型是bind<bool> ,第二个的类型是bind<void> 由于这是两种不同的类型,因此您不能将它们放在一个队列中。 使logout返回bool (即使总是返回true或某物)将是解决此问题的一种方法(可能相对轻松)。

tl; dr:更改logout以返回bool ,然后将队列声明为deque< bind<bool> >

编辑:考虑到许多类型,我建议您为自己创建某种特殊的容器类。 像这样:

class EnqueuedFunc
{
    virtual void operator()() = 0;
};

class LoginFunc : public EnqueuedFunc
{
    bind<bool> func;

    LoginFunc(bind<bool> fn)
    {
        func = fn;
    }
    void operator()()
    {
        fn();
    }
};

class LogoutFunc : public EnqueuedFunc
{
    bind<void> func;

    LoginFunc(bind<void> fn)
    {
        func = fn;
    }
    void operator()()
    {
        fn();
    }
};

然后您的队列是deque<EnqueuedFunc>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM