C ++入門書の5番目の注意事項(第14章オーバーロード操作と型変換)ラムダ関数オブジェクト

1.定義

ラムダは関数オブジェクトです。ラムダを記述した後、コンパイラーは式を無名クラスの無名オブジェクトに変換します。このオブジェクトには、オーバーロードされた関数呼び出し演算子が含まれています。

例えば。

stable_sort(words.begin(),words.end(),[](const string &a,const string &b)
{
    
    return a.size() < b.size();});

//等价于下面的类:
class ShorterString{
    
    
public:
	bool operator()(const string &a,const string &b)
	{
    
    return a.size() < b.size();}
};
stable_sort(words.begin(),words.end(),ShorterString());

テストコード:

std::vector<string> words = {
    
     "a31", "b1" };
stable_sort(words.begin(), words.end(), [](const string& a, const string& b)
    {
    
    return a.size() < b.size(); });    
for_each(words.begin(), words.end(), [](const string& s)
    {
    
    std::cout << s << endl; });
    
std::vector<string> words2 = {
    
     "a31", "b1" };
stable_sort(words2.begin(), words2.end(), ShorterString());
for_each(words2.begin(), words2.end(), [](const string& s)
    {
    
    std::cout << s << endl; });

出力結果は次のとおりです。

b1
a31
b1
a31

2.ラムダのクラスと対応するキャプチャ動作を表します

ラムダによって生成されたクラスは、キャプチャされた値ごとに対応するデータメンバーを確立し、同時にコンストラクターを作成する必要があります。

例えば。

auto wc = find_if(words.begin(),words.end(),[sz](const string &a)
	{
    
    return a.size() > = sz;})

//该 lambda 表达式产生的类将形如:
class SizeComp
{
    
    
	SizeComp(size_t n):sz(n) {
    
     }
	bool operator()(const string &s)const {
    
    return s.size() >= sz;}
private:
	size_t sz;
}; 

テストコード:

void lambda_functionObject_test2(vector<string>::size_type sz)    {
    
     
	 std::vector<string> words = {
    
     "a31", "b1" };
	 auto wc = find_if(words.begin(), words.end(), [sz](const string& a)
	            {
    
    return a.size() >= sz; });
	std::cout << *wc << endl;
	 
	auto wc2 = find_if(words.begin(), words.end(), SizeComp(sz));
	std::cout << *wc2 << endl;
}
lambda_functionObject_test2(3);

出力結果:

a31
a31

3.機能

  • Lambdaは、デフォルトでキャプチャする変数を変更できません。デフォルトでは、lambdaによって生成されたクラスの関数呼び出し演算子はconstメンバー関数です。ラムダが可変として宣言されている場合、呼び出し演算子はconst関数ではなくなります。
  • 変数が参照によってキャプチャされると、プログラムは、ラムダの実行時に参照によってバインドされたオブジェクトが存在することを確認する責任があります。したがって、コンパイラは、ラムダによって生成されたクラスのデータメンバーとして参照を格納せずに、参照を直接使用できます。
  • 値によってキャプチャされた変数はラムダにコピーされます。このとき、ラムダによって生成されたクラスは、キャプチャされた値ごとに対応するデータメンバーを確立し、キャプチャされた変数の値でデータメンバーを初期化するコンストラクターを作成する必要があります。
  • .lambdaによって生成されるクラスには、デフォルトコンストラクタ、代入演算子、およびデフォルトデストラクタは含まれていません。デフォルトのコピー/移動コンストラクタが含まれるかどうかは、通常、キャプチャされた変数のタイプによって異なります。

[見積もり]

[1]コードfunctionObject.h

おすすめ

転載: blog.csdn.net/thefist11cc/article/details/114162719