8

の最後の最近の質問は残念ながら言葉遣いであり、私のものとは別の問題の解決策になったので、ここで私は実際の問題を明確な方法で定式化しようとします.

始める前に、補足として、私は Javascript Engine V8 を C++ アプリケーションに統合しています。例のすべての型はここから来ています。それが、最終的に生の関数ポインターが必要な理由でもあります。しかし、これについては以下で詳しく説明します。

[=]クラス内から、タイプのパラメーターとしてキャプチャー句を含むラムダ式std::functionを別の関数に渡し、そこで生の関数ポインターにキャストする必要があります。

このコードでInvocationCallbackは、 はシグネチャを持つ関数の単なる typedef ですHandle<Value>(Arguments const &)

typedef Handle<Value> (*InvocationCallback)(Arguments const &);

void Bind(string Name, function<Handle<Value>(Arguments const &)> Function)
{
    InvocationCallback* function = Function.target<InvocationCallback>();
}

すべてのラムダ式も同じシグネチャを持っています。この例でHandle<String>は と互換性があることに注意してください。Handle<Value>これも Javascript Engine V8 によって提供されます。

Bind("name", [=](const Arguments& args) -> Handle<Value>{
    Handle<String> result = String::New(Name().c_str());
    return result;
});

C++ では、このラムダをstd::function上記の関数に渡すことができます。しかし、ラムダ式はそれが参照するオブジェクトへの参照も格納していると思います。で指定されたアクセスを何らかの方法[=]で実現する必要があります。std::functionこれが、生の関数ポインターへのキャストが失敗する理由である可能性があります。

InvocationCallback* function = Function.target<InvocationCallback>();

コンパイル時エラーも実行時エラーもありませんが、デバッガーは結果が null ポインターになることを通知します。しかし、さらに処理するには生の関数ポインタが必要です。std::bind最初に参照またはthisポインターを指定した後、ラムダを変換できると思います。

更新:ラムダから状態を取得することは不可能に思われるため、これを試しました。コンパイルfunctionされますが、null ポインターになります。

Bind("name", this, [](Base* object, const Arguments& args) -> Handle<Value>{
    return v8::String::New(((Derived*)object)->Name().c_str());
});

void Bind(string Name, Module *Object, function<Handle<Value>(Module*, Arguments const &)> Function)
{
    function<Handle<Value>(Arguments const &)> method = std::bind(Function, Object, std::placeholders::_1);
    InvocationCallback* function = method.target<InvocationCallback>();

}
4

2 に答える 2

5

キャプチャするラムダはクロージャであるため、できません。したがって、状態があります(インスタンス変数を持つオブジェクトです)。関数ポインターには状態がありません。したがって、1) 関数ポインターを必要とする使用している API では、状態を渡す場所にユーザー データ引数を渡すこともできるか、2) 状態をグローバル変数などに格納する必要があります。

スタック オーバーフローで「コールバックするメンバー関数」を検索すると、アイデアが得られます (基本的には、メンバー関数 をoperator()コールバックとして使用する必要があります)。

于 2013-04-01T20:32:45.697 に答える