C++のlambdasは関数ではなくオブジェクトなので、前方宣言は正しい用語ではありません。コード:
std::function<int(int)> bar;
は、変数を宣言します(その型は「ノー関数へのポインタ」のデフォルト値を持つ)を割り当てることを強制していません。あなたはそれへの呼び出しをコンパイルすることもできます...例えば、コード:
#include <functional>
#include <iostream>
int main(int argc, const char *argv[]) {
std::function<int(int)> bar;
std::cout << bar(21) << "\n";
return 0;
}
(ただし実行時には狂った動作をします)。
bar = [](int x){ return x*2; };
コールが正常にコンパイルされ、出力として42
を生成するプログラムになります右の前に:あなたは互換性のあるstd::function
変数にラムダを割り当て、例えば追加することができた
C++でラムダを驚かせることができるいくつかの非明白な事柄(あなたがこのコンセプトを持つ他の言語を知っているならば)は次の通りです:
各ラムダ[..](...){...}
には、シグネチャが完全に同一であっても、異なる互換性のないタイプがあります。たとえば、decltype([] ...)
のようなものを使用する唯一の方法があるので、ラムダ型のパラメータを宣言することはできませんが、コールサイトの他の[]...
フォームと互換性がないため、この関数を呼び出す方法はありません。これはstd::function
によって解決されるので、ラムダを渡すか、コンテナに保管する必要がある場合は、std::function
を使用する必要があります。
ラムダは値で地元の人々をキャプチャすることができます(ただし、ラムダmutable
を宣言しない限り、彼らはconst
だ)または参照による(ただし、参照されたオブジェクトの寿命を保証することはラムダの寿命が最大であるよりも短くなりませんプログラマー)。 C++にはガベージコレクタがなく、これは "上向きFunarg"問題を正しく解決するために必要なものです(スマートポインタを取り込むことで回避できますが、リークを避けるために参照ループに注意する必要があります)。
他の言語とは異なり、lambdaをコピーすることができます。コピーすると、内部で取り込まれたバイナリ変数のスナップショットが作成されます。これは可変状態のために非常に驚くかもしれません、そして、私は値によって値が取り込まれた理由がデフォルトでconst
だと思います。
std::function<int(int)> timesK(int k) {
return [k](int x){ return x*k; };
}
1つの微妙な違いにもラムダキャプチャ参照と
std::function<int(int)> timesK(int k) {
struct __Lambda6502 {
int k;
__Lambda6502(int k) : k(k) {}
int operator()(int x) {
return x * k;
}
};
return __Lambda6502(k);
}
のような基本的には次のとおりです。
合理化とラムダに関する詳細の多くを覚えておく方法は、それがコードのようなものです(通常はメンバーとしての参照を含むクラスはコピーできません)。
ラムダに名前を付ける場合は、通常の機能にするだけでよいでしょう。 – Brian
@ブライアン知っているとそれは意味をなさない。私が質問する主な理由は好奇心であり、その可能性を知りたいのです。 – MxNx
FYI; 'std :: function'はラムダを格納することができます。ラムダには 'std :: function <...>'という型はありません。むしろ独自の一意の名前のない型を持ちます。ラムダを変数に直接格納するには、その変数の型が(autoまたはテンプレートの引数型の減算によって)推測されていればよい。 'std :: function'にはテンプレート引数型の控除の原理を使ってラムダ引数を取ることができるテンプレートコンストラクタがあります。 –
Mankarse