私の最後の最近の質問は残念ながら言葉遣いであり、私のものとは別の問題の解決策になったので、ここで私は実際の問題を明確な方法で定式化しようとします.
始める前に、補足として、私は 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>();
}