C ++ 14 zaten jenerik lambda içerdiğinde, C ++ 20'de tanıtılan şablon lambda ihtiyacı nedir?


99

aşağıdakileri yazmayı mümkün kılan genel lambdalar sundu:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

Bu genel lambda'nın functıpkı şablonlu bir işlevin funcçalışacağı gibi çalıştığı çok açıktır .

C ++ komitesi neden genel lamda için şablon sözdizimi eklemeye karar verdi?


5
Bağımsız değişkenlerden veya dönüş türünden farklı bir şablon türü kullanmanız gerekirse ne olur ? Ya vücudun içinde ihtiyaç duyulursa?
Bir programcı dostum

Ben söylendi bu ilginç kullanım böyleydi.
Max Langhof

Farklı lambda sürümlerinin karşılaştırması için buna bakın: modernescpp.com/index.php/more-powerful-lambdas-with-c-20
schoetbi

Yanıtlar:


115

C ++ 14 genel lambdalar, operator ()şuna benzer bir functor oluşturmanın çok güzel bir yoludur :

template <class T, class U>
auto operator()(T t, U u) const;

Ama bunun gibi değil:

template <class T>
auto operator()(T t1, T t2) const; // Same type please

Ne de böyle:

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

Böyle de değil (aslında kullanmak biraz zor olsa da):

template <class T>
auto operator()() const; // No deduction

C ++ 14 lambdalar iyidir, ancak C ++ 20 bu durumları sorunsuz bir şekilde uygulamamıza izin verir.


2
Güzel ve öz. Sadece şunu ekliyoruz: İlk (aynı türler) (auto a, decltype(a) b)C ++ 14 ile çözülebilir .
Sebastian Mach

13
@SebastianMach neredeyse. Bu çözümle bçıkarılamaz ve argümanı dolaylı olarak aonun yerine türüne dönüştürülür .
Quentin

32

C ++ 20'de şablonlu lambdalar kullanabildiğiniz için türlerinizi bir SFINAE ifadesinden daha kolay bir şekilde kısıtlayabilirsiniz:

auto lambda = []<typename T>(std::vector<T> t){};

Bu lambda yalnızca vektör türleriyle çalışacaktır.


8
constevalYeni sözdizimi ile nasıl ilişkilidir? Harika ve hepsi, ama alaka düzeyini anlamıyorum.
StoryTeller - Unslander Monica

Daha soruya bir cevap daha lambda ifadesi ne C ++ 20 eklenti hakkında bir bilgidir
Antoine Morrier

24

Öneri C ++ 20 kabul edildi örneklerle uzun motivasyon bölümü vardır. Bunun öncülü şudur:

Yazar tarafından jenerik lambdaları tanımlamak için mevcut sözdiziminin yetersiz görülmesinin birkaç temel nedeni vardır. İşin özü, normal işlev şablonlarıyla kolayca yapılabilen bazı şeylerin, jenerik lambdalarla yapılabilecek önemli çember atlama gerektirmesidir veya hiç yapılamaz. Yazar, lambdaların C ++ 'ın onları desteklemesi için yeterince değerli olduğunu düşünüyor. normal işlev şablonlarının yanı sıra.

Aşağıda epeyce örnek var.


21

C ++ 20'de sunulan lambdalar için yeni "tanıdık şablon sözdizimi"  , C ++ 17 alternatiflerine kıyasla gibi for_types ve  for_rangeuygulanabilir ve çok daha okunaklı hale getirir  .

(kaynak: C ++ 20 lambdas ile derleme zamanı yinelemesi )

Hem C ++ 14 hem de C ++ 17 genel lambdalarda yapılabilecek başka bir ilginç şey, doğrudan operator() bir şablon parametresini açıkça ileterek çağırmaktır  :

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

Yukarıdaki C ++ 14 örneği oldukça işe yaramaz: operator() argümana bir ad vermeden ve kullanmadan lambda gövdesinde  sağlanan türe atıfta bulunmanın bir yolu yoktur  decltype. Ek olarak, ihtiyacımız olmasa bile bir tartışmayı geçmek zorunda kalırız.

C ++ 20 örneği, T'nin lambda gövdesinde nasıl kolayca erişilebilir olduğunu ve artık bir boş lambda'nın keyfi olarak şablonlanabileceğini gösterir. Bu, yukarıda belirtilen derleme zamanı yapılarının uygulanması için çok faydalı olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.