简体   繁体   English

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

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

In my C++ application, I have 2 threads: (i) main thread, (ii) background thread. 在我的C ++应用程序中,我有2个线程:(i)主线程,(ii)后台线程。 I have a class defined as: 我有一个类定义为:

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() and helper::logout() functions (and several other member functions with various return types and # of params and param types) are called on the main thread. 在主线程上调用了helper :: login()和helper :: logout()函数(以及其他几种具有各种返回类型以及#和param和param类型的成员函数)。 In the implementations of these functions, the corresponding internal functions are to be enqueued in a queue, and the background thread calls these internal functions in the order in which they were enqueued. 在这些函数的实现中,将相应的内部函数放入队列中,并且后台线程按将其排入队列的顺序调用这些内部函数。 So something like this: 所以像这样:

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

All this time the background thread is running, waiting for the queue to fill up, and as soon as it does, this background thread would start calling the functions in the queue: 一直以来,后台线程都在运行,等待队列填满,并且一旦这样做,后台线程就会开始调用队列中的函数:

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

So the question is, how do I define such a queue? 所以问题是,如何定义这样的队列?

deque<???> queue;

What could be the data type for this queue such that it can hold callback functions with different signatures in the same queue? 该队列的数据类型可能是什么,以便它可以在同一队列中保存具有不同签名的回调函数?

EDIT: Here's the solution (thanks to J. Calleja): 编辑:这是解决方案(感谢J. Calleja):

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

and then call the functor like this: 然后像这样调用函子:

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

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

You may use boost::function if you normalize the return type or ignore it. 如果您对返回类型进行规范化或忽略它,则可以使用boost :: function This library defines a wrapper that can store any element that matches your signature (function or functor). 该库定义了一个包装器,该包装器可以存储与您的签名(函数或函子)匹配的任何元素。

Using your example: 使用您的示例:

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

This example ignores the return type as it declares the functions returning void. 此示例忽略返回类型,因为它声明函数返回void。 If you want to know the return value, you have to make logout return a bool and change the declaration to: 如果您想知道返回值,则必须使注销返回布尔值并将声明更改为:

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

I believe the type for the first one is bind<bool> and for the second it is bind<void> . 我相信第一个的类型是bind<bool> ,第二个的类型是bind<void> As these are two different types, you can't put them into one queue. 由于这是两种不同的类型,因此您不能将它们放在一个队列中。 Making logout return a bool (even if it always returns true or something) would be one (presumably relatively painless) way to solve this issue. 使logout返回bool (即使总是返回true或某物)将是解决此问题的一种方法(可能相对轻松)。

tl;dr: Change logout to return a bool , and then declare your queue as deque< bind<bool> > . tl; dr:更改logout以返回bool ,然后将队列声明为deque< bind<bool> >

EDIT: Considering the many types, I suggest that you create some kind of special container class for yourself. 编辑:考虑到许多类型,我建议您为自己创建某种特殊的容器类。 Something like this: 像这样:

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

And then your queue is deque<EnqueuedFunc> . 然后您的队列是deque<EnqueuedFunc>

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

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