7

std::function<>C++11 が利用できない場合の代用として、どの構造を使用する必要がありますか?
代替手段は、基本的に、以下の例のように、あるクラスのプライベート メンバー関数に別のクラスからアクセスできるようにする必要があります (std::function の他の機能は使用されません)。クラス Foo は固定されており、あまり変更できません。クラス Bar にしかアクセスできません。

class Foo {
  friend class Bar; // added by me, rest of the class is fixed
  private:

  void doStuffFooA(int i);
  void doStuffFooB(int i);
};

class Bar {
  public:

  Bar( Foo foo, std::function< void (const Foo&, int) > func ) {
    myFoo = foo;
    myFooFunc = func;
  };

  private:

  doStuffBar( const &Foo foo ) {
    myFooFunc( foo, 3 );
  }

  Foo myFoo;
  std::function< void (const Foo&, int) > myFooFunc;
}

int main() {

  Foo foo(...);

  Bar barA( foo, &Foo::doStuffFooA );

  Bar barB( foo, &Foo::doStuffFooB );
  ...
}
4

1 に答える 1

10

C++11 より前の std::function に似たものはありますか?

はい。Boost.Function ( boost::function<>) があります。これは最近 C++ 標準ライブラリの一部になり、 の参照実装を提供しましたstd::function<>。同様に、Boost.Bind( boost::bind<>()) が標準に採用され、 になりましstd::bind<>()た。

任意の型の呼び出し可能なオブジェクトを保持するための型消去と呼ばれる手法を実装します。以下は、そのようなクラス テンプレートをゼロから定義する方法の可能な、例示的な実装です (実稼働コードでは使用しないでください。これは単なる例です)。

#include <memory>

template<typename T>
struct fxn { };

template<typename R, typename... Args>
struct fxn<R(Args...)>
{

public:

    template<typename F>
    fxn(F&& f) 
        : 
        _holder(new holder<typename std::decay<F>::type>(std::forward<F>(f)))
    { }

    R operator () (Args&&... args)
    { _holder->call(std::forward<Args>(args)...); }

private:

    struct holder_base
    { virtual R call(Args&&... args) = 0; };

    template<typename F>
    struct holder : holder_base
    {
        holder(F&& f) : _f(std::forward<F>(f)) { }
        R call(Args&&... args) { return _f(std::forward<Args>(args)...); }
        F _f;
    };

    std::unique_ptr<holder_base> _holder;
};

#include <iostream>

int main()
{
    fxn<void()> f = [] { std::cout << "hello"; };
    f();
}
于 2013-03-02T14:47:00.883 に答える