2016-05-13 6 views
2
struct myclass 
{ 
    myclass(void(*)()) {} 
}; 

void test1(void(*)()) {} 
void test2(myclass) { } 
void cb() {} 

int main() 
{ 
    test1(cb);  // works 
    test2(cb);  // works 
    test1([](){}); // works 

    test2([](){}); // does not work, why? there's no "explicit" keyword next to myclass. 

} 

これはなぜ機能しないのですか?lambaを関数ptrに暗黙的に変換してクラスを作成する

以下は明らかに機能しますが、私はそれを使用したくありません。

 test2(myclass([]{})); 

注:私はstd::function<void()>>を受け入れるようにしたくないと私はどちらかtemplate<T> myclass(T f) {}を作成する必要はありません。

答えて

3

をあなたが唯一のユーザー定義の変換ができ - ユーザーが定義されているポインタのカウントを機能するようにしてラムダを。代わりに、明示的に関数ポインタ変換を行うために、いくつかのsorceryを使用します。

test2(+[](){}); 

も注意引数なしのラムダ中括弧はオプションなので、これも動作すること:

test2(+[]{}); 
+0

ええ、私はすでに括約筋について知っていた。なぜ私はそこにいたのですか?私は+トリックのthoについては全く知らなかった。大変ありがとうございました! – James

+0

OMG!それは恐ろしいことだ。私はそれを使用して想像することができますが、何が起こっているかを事前に説明する10行のコメントがあるだろう! –

+1

@Martinなぜ10行コメントが必要ですか?一度それを見て、それを見て、それが何を意味するかを知っている。 – Barry

2

は、変換シーケンスで1つのユーザ定義変換のみを持つことができます。試してみてください:

test2(static_cast<void(*)()>([](){})); 

または:

test2(static_cast<myclass>([](){})); 
+0

[デモ](https://でideone.com/PerrSL) –

+0

ユーザー定義の変換の答えをUpvoted。単にそれがもう少し完全だったので(それには+「魔法」があったので)、バリーのものが受け入れられました。私はそれについて全く考えていなかったので、病気です。 – James

関連する問題