在我的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()函数(以及具有各种返回类型和#spams和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();
答案 0 :(得分:1)
如果您规范化返回类型或忽略它,则可以使用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的函数。如果您想知道返回值,则必须使logout返回bool并将声明更改为:
typedef boost::function<bool ()> Command;
答案 1 :(得分:0)
我认为第一个的类型是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>
。