5

私は次のものを持っています:

typedef std::function<bool (const std::string&)> SomethingCoolCb;

class ClassA
{
public:
    void OnSomethingCool(const SomethingCoolCb& cb)
    {
        _cb = cb;
    }

private:
    SomethingCoolCb _cb;
};

class ClassB
{
public:
    ClassB();
    bool Juggle(const std::string& arg);

private:
    ClassA _obj;
};

ClassB ::_objへのコールバックとしてClassB::Juggle()メンバー関数を指定したいと思います。C ++ 11でそれを行う適切な方法は(ClassBのコンストラクターで):

ClassB::ClassB()
{
    _obj.OnDoSomethingCool(
        [&](const std::string& arg) -> bool
        {
            return Juggle(arg);
        });
}

私が理解していることから、コンパイラーは上記のラムダコードからstd::functionオブジェクトを作成します。したがって、コールバックが呼び出されると、std :: function :: operator()メンバーが呼び出され、ClassB :: Juggle()を直接呼び出す代わりに、ClassB :: Juggle()が呼び出されます。私が裏で何が起こっているかについて間違えない限り、それはすべて少し非効率的であるように思われます。もっと良い方法はありますか?

4

1 に答える 1

6

std::function本当にポリモーフィック関数が必要な場合にのみ使用してください。それ以外の場合はテンプレートにします。

メンバー関数をファンクターの使用に適合させ、std::mem_fn次にbindオブジェクトを最初の引数に適合させるために、結果のファンクターをコールバックとして機能させることができます。

サンプル:

#include <string>
#include <functional>

template<typename F>
class ClassA
{
public:
    ClassA(F f) : _cb(f) {}

private:
    F _cb;
};

class ClassB
{
public:
    ClassB() 
  : _obj(std::bind(&ClassB::Juggle, this, 
                   std::placeholders::_1)) 
  {}
  bool Juggle(const std::string& arg) {return true;}
private:
    ClassA<decltype(std::bind(
                      std::declval<bool (ClassB::*)(const std::string&)>()
                      , std::declval<ClassB*>()
                      , std::placeholders::_1
                      ) ) > _obj;
};

int main()
{
  ClassB b;
  return 0;
}

これは、ひどく醜いという犠牲を払って、機能のコストを回避します。

于 2012-05-07T14:48:42.563 に答える