[英]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.