C 11: lambda ifadesi nedir?
C 11: lambda ifadesi nedir? Ne zaman kullanmalıyım? Ne sınıf sorun bunların olası giriş önce değildi çözer mi?
Birkaç örnek ve durumlarda kullanmak faydalı olacaktır.
CEVAP
Sorun
C std::for_each
ve çok kullanışlı olabilir std::transform
, jenerik gibi yararlı fonksiyonları içerir. Ne yazık ki, özellikle de eğer uygulamak istiyorum functor belirli bir işlevi için eşsiz ise kullanmak için oldukça hantal olabilir.
#include <algorithm>
#include <vector>
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
void func(std::vector<int>& v) {
f f;
std::for_each(v.begin(), v.end(), f);
}
Eğer sadece f Bir kez ve belirli bir yerde kullanırsanız abartılı bir şey önemsiz ve bir bütün sınıf yazılı kapalı gibi görünüyor.
C 03 aşağıdaki gibi, eşleme yerel tutmak için yazmak için cazip olabilir:
void func2(std::vector<int>& v) {
struct {
void operator()(int) {
// do something
}
} f;
std::for_each(v.begin(), v.end(), f);
}
ancak bu, f
C 03 şablon işlev geçirilemez izin verilmez.
Yeni çözüm
C Lambda 11 struct f
yerine satır içi, isimsiz bir functor yazmak için izin tanıttı. Küçük, basit bir örnek için bu korumak için okumak için daha temiz (bir yerde her şey tutar) ve potansiyel olarak daha basit, en basit şekliyle, örneğin:
void func3(std::vector<int>& v) {
std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}
Lambda fonksiyonları sadece anonim funktorlar için sözdizimsel şeker.
Türlerini döndürür
Basit durumlarda dönüş lambda yazın, örneğin için birebir:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; }
);
}
dönüş türü olamaz derleyici tarafından kurtuldu hızla durumlarda karşılaşacağınız daha karmaşık Lambda yazmaya başladığınızda ancak, örneğin:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
Bu sorunu çözmek için açıkça lambda fonksiyon dönüş türü, -> T
kullanarak belirtmek için izin verilir:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
"Yakalama" değişkenleri
Şimdiye kadar hiçbir şey içindeki lambda geçti neydi dışında değil kullandık, ama aynı zamanda diğer değişkenler kullanabiliriz, lambda içinde. Eğer diğer değişkenleri erişmek istiyorsanız, şimdiye kadar bu örneklerde kullanılmamış olan yakalama maddesinin (ifade []
), örneğin kullanabilirsiniz:
void func5(std::vector<double>& v, const double& epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](double d) -> double {
if (d < epsilon) {
return 0;
} else {
return d;
}
});
}
=
&
kullanarak belirtebilirsiniz iki referans ve değer ile çekebilirsiniz:
[&epsilon]
referans ve yakalar[&, epsilon]
yakalama varsayılan şekilde fotoğraf çekmek istediğimizi başvuru ve olduğunu belirtin[=, &epsilon]
epsilon
varsayılan olarak, ama değeri referans yerine yakalama kullanın
operator()
const
yakalar bunları varsayılan olarak erişim const
olacağını ima ile varsayılan olarak oluşturulur. Bu, her biri aynı sonucu üretecektir aynı giriş yapabilir, ancak mark the lambda as mutable
üretilen operator()
const
değil istemek için çağrı etkiye sahiptir.
Bir arasındaki fark 'kapatma'...
Lambda ifadesi alınıyor Özellik adı...
Scala yazın Lambda nedir ve faydaları ...
Bu 'Lambda herkes demişken tutar&...
Lambda nedir?...