lvalueラムダクロージャーは常にrvalue関数パラメーターとして渡すことができることがわかりました。
次の簡単なデモをご覧ください。
#include <iostream>
#include <functional>
using namespace std;
void foo(std::function<void()>&& t)
{
}
int main()
{
// Case 1: passing a `lvalue` closure
auto fn1 = []{};
foo(fn1); // works
// Case 2: passing a `lvalue` function object
std::function<void()> fn2 = []{};
foo(fn2); // compile error
return 0;
}
ケース2は標準の動作です(std::functionデモ目的で単にを使用しましたが、他のタイプも同じように動作します)。
ケース1はどのように、そしてなぜ機能するのですか?fn1関数が返された後の閉鎖の状態はどうですか?
std::functionラムダから推定できないのか」ということでした。プログラムはのテンプレート引数を推定しようとしないstd::functionので、暗黙の変換に問題はありません。
std::functionラムダクロージャを受け入れる非明示的なコンストラクタがあるため、暗黙の変換があります。ただし、リンクされた質問の状況では、のテンプレートのインスタンス化はstd::functionラムダ型から推測できません。(例えば、std::function<void()>から構成することができる[](){return 5;}、それがvoid以外の戻り値の型を持っているにもかかわらず。
fn1暗黙的に変換されるstd::functionの中でfoo(fn1)。その一時的な関数は右辺値です。