0

私の C++ アプリケーションには、(i) メイン スレッド、(ii) バックグラウンド スレッドの 2 つのスレッドがあります。次のように定義されたクラスがあります。

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() 関数 (および、さまざまな戻り値の型と、params および 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();
4

2 に答える 2

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;
于 2012-08-23T22:01:28.153 に答える
0

最初の型はbind<bool>で、2 番目の型は だと思いますbind<void>。これらは 2 つの異なるタイプであるため、1 つのキューに入れることはできません。この問題を解決するための 1 つの (おそらく比較的簡単な) 方法は、 returnlogoutbool(常に返さtrueれるか何かであったとしても) 作成することです。

tl;dr:logoutを返すように変更しbool、キューを として宣言しますdeque< bind<bool> >

EDIT:多くのタイプを考慮して、自分用に特別なコンテナクラスを作成することをお勧めします。このようなもの:

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>です。

于 2012-08-23T21:16:41.447 に答える