C ++ 20 में पेश किए गए टेम्प्लेट लैम्ब्डा की क्या आवश्यकता है जब C ++ 14 में पहले से ही जेनेरिक लैम्ब्डा है?


99

जेनेरिक लम्बदास की शुरुआत की, जिसने निम्नलिखित लिखना संभव बनाया:

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

यह बहुत स्पष्ट है कि यह जेनेरिक लैंबडा funcएक टेम्पर्ड फंक्शन की तरह funcही काम करेगा।

C ++ समिति ने जेनेरिक लैम्डा के लिए टेम्पलेट सिंटैक्स को जोड़ने का फैसला क्यों किया?


5
क्या होगा अगर आपको तर्कों या रिटर्न प्रकार की तुलना में एक अलग टेम्पलेट प्रकार का उपयोग करने की आवश्यकता है ? और अगर यह शरीर के अंदर की जरूरत है तो क्या होगा?
कुछ प्रोग्रामर

मुझे बताया गया है कि यह एक दिलचस्प उपयोग मामला था।
मैक्स लैंगहॉफ

विभिन्न लैम्ब्डा संस्करणों की तुलना के लिए इसे देखें: modernescpp.com/index.php/more-powerful-lambdas-with-c-20
schoetbi

जवाबों:


115

C ++ 14 जेनेरिक लैम्ब्डा operator ()इस तरह से दिखने वाले फन्नेटर को उत्पन्न करने का एक बहुत अच्छा तरीका है :

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

लेकिन इस तरह नहीं:

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

न ही इस तरह:

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

न ही इस तरह (हालांकि यह वास्तव में उपयोग करने के लिए थोड़ा मुश्किल हो जाता है):

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

C ++ 14 लैम्ब्डा ठीक हैं, लेकिन C ++ 20 हमें इन मामलों को बिना परेशानी के लागू करने की अनुमति देता है।


2
अच्छा और संक्षिप्त। बस इसे जोड़ते हुए: पहला (समान प्रकार) (auto a, decltype(a) b)C ++ 14 में हल किया जा सकता है ।
सेबेस्टियन मच

13
@ सेबेस्टियन माच लगभग। उस समाधान के साथ bगैर-कटौती की जाती है, और इसके तर्क को aबदले में बदले के प्रकार में बदल दिया जाएगा।
क्वेंटिन

32

चूँकि आप C ++ 20 में टेम्पर्ड लैम्ब्डा का उपयोग कर सकते हैं, आप अपने प्रकारों को एक SFINAE अभिव्यक्ति से आसान तरीके से प्रतिबंधित कर सकते हैं:

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

यह मेमना केवल वेक्टर प्रकारों के साथ काम करेगा।


8
constevalनए सिंटैक्स से कैसे संबंधित है? यह शांत है और सभी है, लेकिन मुझे प्रासंगिकता नहीं मिली।
स्टोरीटेलर - Unslander मोनिका

यह सवाल के जवाब की तुलना में
लंबोदर

24

प्रस्ताव है कि सी ++ 20 में स्वीकार कर लिया गया एक लंबा प्रेरणा अनुभाग, उदाहरण के साथ है। इसका आधार यह है:

कुछ प्रमुख कारण हैं कि जेनेरिक लैम्ब्डा को परिभाषित करने के लिए मौजूदा वाक्यविन्यास को लेखक द्वारा अपर्याप्त माना जाता है। इसका सार यह है कि सामान्य फंक्शन टेंपरेचर के साथ आसानी से किए जा सकने वाली कुछ चीजों को जेनेरिक लैंबडास के साथ करने के लिए महत्वपूर्ण हूप जंपिंग की आवश्यकता होती है, या बिल्कुल भी नहीं किया जा सकता है। लेखक का मानना ​​है कि लैम्ब्डा काफी मूल्यवान हैं कि सी ++ उन्हें चाहिए बस के रूप में अच्छी तरह से सामान्य समारोह टेम्पलेट्स।

इसके बाद काफी कुछ उदाहरण हैं।


21

C ++ 20 में पेश किए गए लैम्ब्डा के लिए नया "परिचित टेम्प्लेट सिंटैक्स",  C ++ 17 विकल्पों की तुलना में ऐसे for_types और  for_rangeव्यवहार्य और अधिक पठनीय निर्माण करता है  ।

(स्रोत: संकलन समय C ++ 20 लंबोदा के साथ )

एक और दिलचस्प बात जो C ++ 14 और C ++ 17 जेनेरिक लैम्ब्डा दोनों पर की जा सकती है, सीधे operator() एक टेम्प्लेट पैरामीटर को स्पष्ट रूप से पास करके कॉल  करना है:

सी ++ 14:

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

सी ++ 20:

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

ऊपर दिया गया C ++ 14 उदाहरण काफी बेकार है: operator() तर्क को एक नाम और उपयोग किए बिना लैम्ब्डा के शरीर में  प्रदान किए गए प्रकार का उल्लेख करने का कोई तरीका नहीं है  decltype। इसके अतिरिक्त, हमें एक तर्क पारित करने के लिए मजबूर किया जाता है, भले ही हमें इसकी आवश्यकता न हो।

C ++ 20 उदाहरण से पता चलता है कि लैम्ब्डा के शरीर में T कैसे आसानी से सुलभ है और यह कि एक अशक्त लैम्ब्डा को अब मनमाने ढंग से टेम्पल किया जा सकता है। उपर्युक्त संकलन-समय के निर्माण के कार्यान्वयन के लिए यह बहुत उपयोगी होने जा रहा है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.