簡體   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