2016-04-24 15 views
1

私はラムダをvoid型にキャストして型の削除のために格納する必要がある特別なケースがあります。lambdaをvoid *をキャストして関数ポインタにキャストできないのはなぜですか?

すべてが最初のケースでは動作しますが、2番目のケースでは動作しません。これを解決する方法と、この動作が始まったと定義されている場合もあります。

int main() 
{ 
    auto lambda = [](int x){ 
     std::cerr << x << std::endl; 
    }; 

    //Cast lambda to void* 
    void* vptr = static_cast<void*>(&lambda); 

    //Cast vptr back to lambda and call it 
    (*static_cast<decltype(&lambda)>(vptr))(10); //<--- Ok, compiles and works 

    //Cast vptr to function pointer 
    (*static_cast<void(**)(int)>(vptr))(10); //<--- Compiles but segmentation fault 

    return 0; 
} 
+0

'void(*)(int)'であってはなりませんか? – songyuanyao

+0

@LightnessRacesinOrbitできません。私は基本的な関数ポインタ、メンバ関数ポインタとlambdasを格納することができるデリゲートクラスを書いています。私はまだそれができるだけ速く、他の方法でやってもうまくいきません。 –

+0

ラムダは関数ではありません。大雑把に言えば、それはファンクタ( 'operator() 'を持つ構造体)です。それを(またはそのアドレス)を関数に変換し、その関数を呼び出すと、未定義の動作が起こります。 – Peter

答えて

3

ラムダは、operator()部材と隠れクラス型のインスタンスである関数—ありません。したがって、あなたのラムダのアドレスを関数ポインタにキャストすることは決してうまくいきません。

この最初の方法(動作する)を使用するか、この要件が完全に蒸発するように、好ましくは周囲のものを変更してください。それは気違いだから。

+0

ありがとう、それも私の質問に答えた –

+0

それは競争だったか分からなかった。コードをアップロードして、自分で見ることができ、より良い方法で解決する方法を教えてください。 –

+1

*ラムダのアドレスを関数ポインタにキャストすることは決してできません*。実際には、ラムダをキャプチャしていない場合に動作します。例として 'fn = void(*)();を使用しています。 fn f = [](){} '。この場合、ラムダは関数ポインタに減衰します。 – skypjack

1

例としてノン、関数ポインタにラムダ崩壊をキャプチャ:キャプチャラムダはない

#include<functional> 

int main() { 
    using Fn = void(*)(); 
    using Fnp = void(**)(); 
    Fn fn = [](){ }; 
    Fnp p = &fn; 
    (*p)(); 
} 


この場合、この機能を悪用することができます。

+0

はい、それは私が質問をした理由です。私は関数のポインタに非キャプチャラムダをキャストすることはできますが、それは明白な理由では機能しません。 –

+0

実際には崩壊する。 – skypjack

関連する問題