2016-01-13 20 views
15

通常、Cスタイルの関数ポインタにキャプチャなしのC++ラムダshould be convertableがあります。何らかの形で、std::function::targetを使用して変換すると機能しません(つまりnullptrを返します)。target_typeも同じであるように見えますが、署名の種類に一致しません。 VC13とGCC 5.3/5.2.0でテストキャプチャレスラムダはstd :: functionに格納されているときに関数ポインタに変換できません

/4.8

最小限試験例:出力

0 
0 
1 
<address> 

1 
<address> 
1 
<address> 

実際の出力であろうと予想

#include <functional> 
#include <iostream> 

void Maybe() { 

} 

void callMe(std::function<void()> callback) { 
    typedef void (*ftype)(); 
    std::cout << (callback.target_type() == typeid(ftype)) << std::endl; 
    std::cout << callback.target<ftype>() << std::endl; 
} 

int main() { 
    callMe([]() {}); 
    callMe(Maybe); 
} 

質問:ラムダの署名が渡された関数と異なるのはなぜですか?

+0

を_「...に変換する必要があります...」 _ - 引用が必要です。 – Useless

+4

@Useless Hmmm、[引用はこちら](http://stackoverflow.com/a/28746827/1413395)。 –

+0

@πάνταῥεῖありがとう、私は質問 –

答えて

15

最初の呼び出しでは、std::functionはラムダをポインタに崩壊させずに、実際のタイプ(実際にはvoid()ではない)でポインタを格納するだけです。

あなたは、単に単項+を使用することにより、後者でstd::functionを構築前にポインタに崩壊するラムダを強制することができます。

callMe(+[](){}); 
// ^
+4

+1にそれを含めましたが、私は本当にこの積分型/ポインタ型強制のためのこのハックを嫌います。それは、意図をあまりにもあいまいにするだけです。専用の関数にこれをラップすることで明示的にする方がよい。 –

+0

私たちは[this Q&A](http://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this/18889029?s=1|0.0000#18889029)の一束を見つけましたか? –

+0

@πάνταῥεῖ厳密に重複しているわけではありません(他のタイプは型減算と過負荷解決に関するものです)が、実際にはかなり強く関連しています。 – Quentin

関連する問題