1

クラス内の「this」ポインターをパラメーターとしてキャプチャーしてラムダ式を保存する際に問題があります。次のように typedef を作成しました。

typedef void(*func)();

以下のこのコードは正常に動作します。

#include <iostream>
using namespace std;

typedef void(*func)();

class A {
public:
    func f;
};

class B {
public:
    A *a;

    B() {
        a = new A();
        a->f = [](){
            printf("Hello!");
        };
    }
};

int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

まだキャプチャはありませんが、ラムダで「この」ポインタをキャプチャしたい場合、エラーがスローされます。キャプチャでtypedefを作成するにはどうすればよいですか? 私はこのようなことをしたい:

#include <iostream>
using namespace std;

typedef void(*func)();

class A {
public:
    func f;
};

class B {
public:
    A *a;

    B() {
        a = new A();

        //There is a problem with [this]
        a->f = [this](){
            //Method from class B using "this" pointer
            this->p();
        };
    }
    void p() {
        printf("Hello!");
    }
};

int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

私は何を間違っていますか?説明してください。ありがとう。

4

2 に答える 2

5

キャプチャ付きラムダから関数ポインタに変換することはできません。キャプチャ付きラムダには関数ポインタよりも多くの情報が含まれているためです (関数のアドレスだけでなく、キャプチャされた変数も含まれています)。 .

に変更typedef void(*func)();typedef std::function<void()> func;て、コピー可能な関数型を保持できるものを取得します。

于 2013-02-19T09:02:30.877 に答える
3

std::functionAngew が上で述べたように、関数ポインタだけでなく、クラス テンプレートを使用する必要があります。コードは次のようになります (2 番目の例からのコピー)

#include <iostream>
#include <functional>
#include <memory>
using namespace std;



class A {
public:
    std::function<void> f;
};

class B {
public:
    shared_ptr<A> a;  // Better ownership

    B() 
     : a(new A())
    {
        // Now this should work
        a->f = [this](){
            //Method from class B using "this" pointer
            this->p();
        };
        // Note, you could just do this instead of a lambda:
        // a->f = bind(b::p, this);
    }
    void p() {
        printf("Hello!");
    }
};

int main() {
    B *b = new B();
    b->a->f();
    return 0;
}

Aまた、正しい呼び出し可能オブジェクトに加えて、スマート ポインターによる自動クリーンアップを追加し、これを行う方法を示すコードも追加しましstd::bindた。

于 2013-02-19T09:15:03.653 に答える