26 Nisan 2019 Cuma

Closure - Capture By Value

1. İsim Vermeden Capture
Closure içinde kullanılan değişkenlerin kopyasını aldığı için kullanması kolaydır.

Örnek
Elimizde şöyle bir closure olsun.
[=] { return x + 1; } // capture by value
Derleyici şöyle bir kod üretir.
class bar {
  int x;
public:
  bar(int x) : x(x) {}
  int operator()() const { return x + 1; }
};
1.1 Const Değişkenler İçin İsim Vermeden Capture

Örnek
Şöyle yaparız.
int main(){
  const int x = 123;
  auto g = []() { std::cout << x << "\n"; };
  g();
}
const float değişkenler bir sebepten dolayı bu kuralın dışında bırakılmış. Şu kod derlenmez.
int main(){
  const float x = 123;
  auto g = []() { std::cout << x << "\n"; };
  g();
}

2. İsim İle Capture
İsim vererek closure yapınca hangi değişkenlerin kopyasının alındığını görmek daha kolay.

Örnek
Şöyle yaparız. Sadece s değişkenine erişileceği belirtilir.
std::string s{"Test"};
auto T = [s]() { std::cout << s.size() << ' '; };  // make a copy of s
Örnek
İsim vererek closure yapınca aynı zamanda nesneyi move etmek için şöyle yaparız.
std::vector<int> vector;
auto lambda = [vec = std::move(vector)]() { /* the lambda owns the vector now */ });
3. Init Capture
Şöyle yaparız. i değişkeni yaratılır ve value olarak ilklendirilir.
auto inc = [i=0]() mutable { return i++; };
Açıklaması şöyle
The mutable is required because lambdas are const by default, and we need to directly modify the member i.
4. Mutable Closure
Capture By Value kullansak bile capture edilen tüm value değişkenler const kabul edilir. Eğer değişkenin değeri ile oynamak istersek Closure mutable olarak işaretlenmelidir.

Örnek
Şöyle yaparız.
int x = 3;
auto f1 = [x]() mutable
{
  return x++;
};
Örnek
mutable ve const Closure'lar birbirlerini kullanmaz. Şu kod derlenmez.
int x = 3;
auto f1 = [x]() mutable
{
    return x++;
};
auto f2 = [f1]()
{
    return f1();
};

Hiç yorum yok:

Yorum Gönder