2013-06-28 9 views
5

私はラムダへの「参照」をキャプチャしたい、と私は関数ポインタがのように、トリックを行うだろうと思った:ラムダの「参照」を作成するにはどうすればよいですか?

int (*factorial)(int) = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 

が、私はcannot convert from main::lambda<......> to int(_cdecl *)(int)を取得します。

ラムダを指す適切な方法は何ですか?

+3

ラムダは何もキャプチャしなければ関数ポインタに変換できます。 – jrok

+0

あなたが正しいですね。知っておいて、ありがとう。 – sircodesalot

+0

これはほぼhttp://stackoverflow.com/questions/2067988/recursive-lambda-functions-in-c0xの複製です。 – doctorlove

答えて

6

ラムダはステートレスではないため、関数ポインタに変換することはできません。代わりにstd::functionを使用してください。

std::function<int(int)> factorial = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 
+1

これは、「生の」ラムダと比較して、警告として無視できないオーバーヘッドコストを伴います。それぞれの呼び出しは 'virtual'メソッドを呼び出すのとほぼ同じです。それはそれほど悪くはありませんが、コールで行われている作業と比較して、重要です。 – Yakk

+0

@Yakkはい、あなたは 'std :: function'の型消去のコストを支払っています。私は数週間前にその答えを探していただけです:) – Praetorian

+0

「無国籍ではない」とはどういう意味ですか?また、@ Yakkは間接費は何ですか? – sircodesalot

5

これは、あなたがすでに持っているものに近いようになります:関数は再帰的であるため、

std::function<int (int)> factorial = [&](int x){ 
    return (x < 2) 
     ? 1 
     : x * factorial(x - 1); 
}; 

通常、あなたはまた、autoを使用することができますが、この場合には、それは動作しません。

+1

'auto'は機能しません。リンクされた質問を参照してください。 –

+0

@ JesseGood:良い点 - ありがとう。 –

5

すでに良い回答があります。以下は単に好奇心ですが、私はそれを使用するように勧めません。

他の人によると答えたように、ラムダfactorialはそれ自身をキャプチャしようとします。したがって、ステートレスではありません。したがって、関数ポインタへの変換はできません。 (GCC 4.7.2)

#include <iostream> 

    typedef int (*function)(int); 

    int main() { 
     static function factorial = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     std::cout << factorial(5) << '\n'; 
    } 

ラムダは、グローバルまたはstaticオブジェクトをキャプチャする必要はありませんので、あなたがfactorialグローバルまたはstatic変数を作る場合、あなたはそれをキャプチャする必要はありませんし、これが正常に動作します

#include <iostream> 

    typedef int (*function)(int); 

    function make_factorial() { 
     static function factorial = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     return factorial; 
    } 

    int main() { 
     auto factorial = make_factorial(); 
     std::cout << factorial(5) << '\n'; 
    } 

あなたがtypedef排除し、さらに:-)を難読化したい場合:

また、このような工場を作成することができます3210

// This is a function returning a pointer to a function taking an int and returning an int. 
    int (*(make_factorial)())(int) { 
     static int (*factorial)(int) = [](int x){ 
      return (x < 2) ? 1 : x * factorial(x - 1); 
     }; 
     return factorial; 
    } 
関連する問題