සී ++ 11 හි ලැම්බඩා ප්‍රකාශනය යනු කුමක්ද?


1501

සී ++ 11 හි ලැම්බඩා ප්‍රකාශනය යනු කුමක්ද? මම එකක් භාවිතා කරන්නේ කවදාද? ඔවුන් හඳුන්වාදීමට පෙර කළ නොහැකි වූ ගැටලුව කුමක්ද?

උදාහරණ කිහිපයක්, සහ භාවිතා කිරීමේ අවස්ථා ප්‍රයෝජනවත් වනු ඇත.


15
ලැම්බඩා ඉතා ප්‍රයෝජනවත් වූ අවස්ථාවක් මම දැක ඇත්තෙමි: මගේ සගයකු අභ්‍යවකාශ ප්‍රශස්තිකරණ ගැටළුවක් විසඳීම සඳහා මිලියන ගණනක් පුනරාවර්තන කේතයක් කරමින් සිටියේය. නිසි ශ්‍රිතයකට වඩා ලැම්බඩා භාවිතා කරන විට ඇල්ගොරිතම වඩා වේගවත් විය! සම්පාදකයා විෂුවල් සී ++ 2013.
සර්ජියොල්

Answers:


1509

ගැටලුව වන්නේ

C ++ වැනි ප්රයෝජනවත් Generic බලපත්රය යටතේ අවසර ලබා ඇත කාර්යයන් ඇතුළත් std::for_eachහා std::transformඉතා ප්රයෝජනවත් විය හැකි. අවාසනාවකට මෙන් ඒවා භාවිතා කිරීමද ඉතා අපහසු විය හැකිය, විශේෂයෙන් ඔබ අයදුම් කිරීමට කැමති ෆන්ක්ටර් විශේෂිත කාර්යයට අද්විතීය නම්.

#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);
}

ඔබ fඑක් වරක් පමණක් භාවිතා කරන්නේ නම් සහ එම නිශ්චිත ස්ථානයේ දී මුළු පන්තියක්ම ලිවීම ඉතා සුළු දෙයක් ලෙස පෙනේ.

C ++ 03 හි පහත සඳහන් දේ ලිවීමට ඔබ පෙළඹෙනු ඇත.

void func2(std::vector<int>& v) {
  struct {
    void operator()(int) {
       // do something
    }
  } f;
  std::for_each(v.begin(), v.end(), f);
}

කෙසේ වෙතත් මෙය අවසර නැත, C ++ 03 හි අච්චු ශ්‍රිතයකට fයැවිය නොහැක .

නව විසඳුම

සී ++ 11 විසින් ලැම්බඩස් හඳුන්වා දී ඇති අතර එය ප්‍රතිස්ථාපනය කිරීම සඳහා පේළිගත, නිර්නාමික විනෝදයක් ලිවීමට ඉඩ ලබා දේ struct f. කුඩා සරල උදාහරණ සඳහා මෙය කියවීමට වඩා පිරිසිදු විය හැකිය (එය සෑම දෙයක්ම එක තැනක තබා ගනී) සහ නඩත්තු කිරීමට සරල විය හැකිය, උදාහරණයක් ලෙස සරලම ආකාරයෙන්:

void func3(std::vector<int>& v) {
  std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}

ලැම්බඩා කාර්යයන් නිර්නාමික විනෝදකරුවන් සඳහා සින්ටැක්ටික් සීනි පමණි.

ප්‍රතිලාභ වර්ග

සරල අවස්ථා වලදී ලැම්බඩාවේ ආපසු පැමිණීමේ වර්ගය ඔබ වෙනුවෙන් අඩු කරනු ලැබේ, උදා:

void func4(std::vector<double>& v) {
  std::transform(v.begin(), v.end(), v.begin(),
                 [](double d) { return d < 0.00001 ? 0 : d; }
                 );
}

කෙසේ වෙතත් ඔබ වඩාත් සංකීර්ණ ලැම්බඩස් ලිවීමට පටන් ගත් විට, නැවත පැමිණීමේ වර්ගය සම්පාදකයාට අඩු කළ නොහැකි අවස්ථා ඔබට ඉක්මනින් හමුවනු ඇත, උදා:

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;
            }
        });
}

මෙම විසඳීමට ඔබ යොදාගෙන, ලැම්ඩා උත්සවය සඳහා ආපසු වර්ගය නිශ්චිතවම විශේෂණය කිරීමට අවසර ඇත -> T:

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;
            }
        });
}

"අල්ලා ගැනීම" විචල්යයන්

මෙතෙක් අපි ලැම්බඩා වෙත ලබා දුන් දේ හැර වෙනත් කිසිවක් භාවිතා කර නැත, නමුත් අපට ලැම්බඩා තුළ වෙනත් විචල්‍යයන් ද භාවිතා කළ හැකිය. ඔබට වෙනත් විචල්‍යයන්ට ප්‍රවේශ වීමට අවශ්‍ය නම් [], මෙම උදාහරණවල මෙතෙක් භාවිතා කර නොමැති ග්‍රහණ වගන්තිය ( ප්‍රකාශනයේ) භාවිතා කළ හැකිය, උදා:

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;
            }
        });
}

ඔබ භාවිතා නියම කළ හැකි, සමුද්දේශ සහ අගය දෙකම විසින් අල්ලා හැකි &හා =පිළිවෙළින්:

  • [&epsilon] යොමුව මගින් අල්ලා ගැනීම
  • [&] ලැම්බඩා හි භාවිතා වන සියලුම විචල්‍යයන් යොමු මගින් ග්‍රහණය කරයි
  • [=] ලැම්බඩා හි භාවිතා වන සියලුම විචල්‍යයන් අගය අනුව ග්‍රහණය කරයි
  • [&, epsilon] [&] සමඟ විචල්‍යයන් ග්‍රහණය කරයි, නමුත් අගය අනුව එප්සිලෝන්
  • [=, &epsilon] [=] වැනි විචල්‍යයන් ග්‍රහණය කරගනී, නමුත් එප්සිලන් යොමුව අනුව

මෙම ජනනය operator()වේ constනිවැරදිව ග්රහණය වන බව ඇඟවුම සමඟ, පෙරනිමියෙන් constඔබ පෙරනිමියෙන් ප්රවේශ විට. එකම ආදානය සහිත සෑම ඇමතුමක්ම එකම ප්‍රති result ලයක් ලබාmutable දෙන බවට මෙය බලපෑමක් ඇති කරයි, කෙසේ වෙතත් ඔබට ලැම්බඩා සලකුණු කළ හැක්කේ operator()නිපදවන ලද ඉල්ලීම නොවේ const.


9
Ak යක් ඔබ කොටු වී ඇත. ග්‍රහණයකින් තොරව ලැම්බඩාස් ක්‍රියාකාරී ආකාරයේ දර්ශකයන් වෙත ව්‍යංග පරිවර්තනයක් ඇත. පරිවර්තන කාර්යය constසැමවිටම වේ ...
ජොහැන්නස් ෂෝබ් - litb

2
@ ජොහැන්නස්චෝබ්-ලිට්බ් ඔහ් ස්නීකි - ඔබ එය ඉල්ලන විට එය සිදු වේ ()- එය ශුන්‍ය-තර්ක ලැම්බඩා ලෙස සම්මත වේ, නමුත් ලැම්බඩා සමඟ () constනොගැලපෙන නිසා , එය ඉඩ දෙන ආකාරයේ පරිවර්තනයක් සොයයි, එයට ව්‍යංග-වාත්තු ඇතුළත් වේ -To-function-pointer, ඉන්පසු එය අමතන්න! හොර රහසේ!
යක් - ඇඩම් නෙව්රාමොන්ට්

2
සිත්ගන්නාසුළුයි - මම මුලින් සිතුවේ ලැම්බඩා යනු විනෝදකාමීන්ට වඩා නිර්නාමික කාර්යයන් වන අතර , අල්ලා ගැනීම් ක්‍රියා කරන ආකාරය පිළිබඳව ව්‍යාකූල විය.
user253751

51
ඔබේ වැඩසටහනේ ලැම්බඩස් විචල්‍යයන් ලෙස භාවිතා කිරීමට ඔබට අවශ්‍ය නම්, ඔබට මෙය භාවිතා කළ හැකිය: std::function<double(int, bool)> f = [](int a, bool b) -> double { ... }; නමුත් සාමාන්‍යයෙන් අපි සම්පාදකයාට වර්ගය අඩු කිරීමට ඉඩ දෙමු: auto f = [](int a, bool b) -> double { ... }; (සහ අමතක නොකරන්න #include <functional>)
එවර්ට් හෙලන්

11
return d < 0.00001 ? 0 : d;එක් ඔපෙරන්ඩ් එකක් නිඛිල නියතයක් වන විට දෙගුණයක් ආපසු ලබා දීමට සහතික වන්නේ මන්දැයි සෑම කෙනෙකුම තේරුම් නොගනී යැයි මම සිතමි (එයට හේතුව: පරිවර්තනයන් තෝරාගනු ලැබුවද කමක් නැත). වෙනස් කිරීම 0.0 : dසමහර විට උදාහරණය තේරුම් ගැනීමට පහසු වනු ඇත.
ලුන්ඩින්

835

ලැම්බඩා ශ්‍රිතයක් යනු කුමක්ද?

ලැම්බඩා ශ්‍රිතයක C ++ සංකල්පය ආරම්භ වන්නේ ලැම්බඩා කැල්කියුලස් සහ ක්‍රියාකාරී වැඩසටහන්කරණයෙනි. ලැම්බඩා යනු නම් නොකළ ශ්‍රිතයක් වන අතර එය නැවත භාවිතා කිරීමට නොහැකි සහ නම් කිරීමට තරම් වටිනා නොවන කෙටි කේත කුඩා කොටස් සඳහා ප්‍රයෝජනවත් වේ (සත්‍ය ක්‍රමලේඛනයේදී, න්‍යායට නොවේ).

C ++ හි ලැම්බඩා ශ්‍රිතයක් මේ ආකාරයෙන් අර්ථ දක්වා ඇත

[]() { } // barebone lambda

නැතහොත් එහි සියලු තේජසින්

[]() mutable -> T { } // T is the return type, still lacking throw()

[]අල්ලා ගැනීමේ ලැයිස්තුව, ()තර්ක ලැයිස්තුව සහ {}ක්‍රියාකාරී ශරීරය වේ.

අල්ලා ගැනීමේ ලැයිස්තුව

ග්‍රහණ ලැයිස්තුව මඟින් ලැම්බඩාවේ පිටත සිට ක්‍රියාකාරී ශරීරය තුළ තිබිය යුතු දේ සහ කෙසේද යන්න නිර්වචනය කරයි. එය එක්කෝ විය හැකිය:

  1. අගය: [x]
  2. යොමු කිරීමක් [& x]
  3. යොමුව අනුව විෂය පථයේ දැනට පවතින ඕනෑම විචල්‍යයක් [&]
  4. 3 ට සමාන නමුත් අගය අනුව [=]

ඉහත සඳහන් ඕනෑම එකක් කොමාවකින් වෙන් කළ ලැයිස්තුවකට ඔබට මිශ්‍ර කළ හැකිය [x, &y].

තර්ක ලැයිස්තුව

තර්ක ලැයිස්තුව වෙනත් ඕනෑම C ++ ශ්‍රිතයකට සමාන වේ.

ක්‍රියාකාරී ශරීරය

ලැම්බඩා සැබවින්ම හැඳින්වූ විට ක්‍රියාත්මක වන කේතය.

ප්‍රතිලාභ වර්ගය අඩු කිරීම

ලැම්බඩා සතුව ඇත්තේ එක් ආපසු ප්‍රකාශයක් පමණක් නම්, ආපසු පැමිණීමේ වර්ගය මඟ හැරිය හැකි අතර එයින් ගම්‍ය වන ආකාරයේ වේ decltype(return_statement).

විකෘති

ලැම්බඩා විකෘති ලෙස සලකුණු කර ඇත්නම් (උදා []() mutable { }) එය අගය මගින් ග්‍රහණය කරගත් අගයන් විකෘති කිරීමට අවසර දෙනු ලැබේ.

නඩු භාවිතා කරන්න

අයිඑස්ඕ ප්‍රමිතියෙන් අර්ථ දක්වා ඇති පුස්තකාලය ලැම්බඩාස් වෙතින් විශාල වශයෙන් ප්‍රතිලාභ ලබා දෙන අතර බාර් කිහිපයක් භාවිතා කිරීමේ හැකියාව ඉහළ නංවයි.

සී ++ 14

සී ++ දී ලැම්බඩා 14 විවිධ යෝජනා මගින් දීර් extended කර ඇත.

ආරම්භක ලැම්බඩා අල්ලා ගැනීම

අල්ලා ගැනීමේ ලැයිස්තුවේ අංගයක් දැන් ආරම්භ කළ =හැකිය. මෙය විචල්යයන් නැවත නම් කිරීමට සහ චලනය කිරීමෙන් අල්ලා ගැනීමට ඉඩ සලසයි. සම්මතයෙන් ගත් උදාහරණයක්:

int x = 4;
auto y = [&r = x, x = x+1]()->int {
            r += 2;
            return x+2;
         }();  // Updates ::x to 6, and initializes y to 7.

සහ විකිපීඩියාවෙන් ලබාගත් එකක් අල්ලා ගන්නේ කෙසේද යන්න පෙන්වයි std::move:

auto ptr = std::make_unique<int>(10); // See below for std::make_unique
auto lambda = [ptr = std::move(ptr)] {return *ptr;};

සාමාන්‍ය ලැම්බඩාස්

ලැම්බඩාස් දැන් සාමාන්‍ය විය හැකිය ( අවට විෂය පථයේ කොතැනක හෝ වර්ග අච්චු තර්කයක් නම් මෙහි autoසමාන වේ ):TT

auto lambda = [](auto x, auto y) {return x + y;};

වැඩි දියුණු කළ ප්‍රතිලාභ වර්ගය අඩු කිරීම

C ++ 14 සෑම ශ්‍රිතයක් සඳහාම අඩු කළ ප්‍රතිලාභ වර්ග වලට ඉඩ දෙන අතර එය පෝරමයේ ක්‍රියාකාරිත්වයට පමණක් සීමා නොවේ return expression;. මෙය ලැම්බඩාස් දක්වා ද ව්‍යාප්ත වේ.


2
ඉහත සඳහන් කළ ලැම්බඩා ග්‍රහණයන් සඳහා වන ඔබේ උදාහරණයේ දී, ඔබ () සමඟ ලැම්බා ක්‍රියාකාරිත්වය අවසන් කරන්නේ ඇයි? මෙය [] () like} () ලෙස පෙනේ; වෙනුවට [](){};. X හි අගය 5 නොවිය යුතුද?
රාමක්‍රිෂ්ණන් කන්නන්

7
Am රාමක්‍රිෂ්ණන් කන්නන්: 1) () ලැම්බඩා නිර්වචනය කළ විගසම ඇමතීමට සහ එහි ප්‍රතිලාභ අගය ලබා දීමට ඇත. විචල්ය y යනු නිඛිලයක් මිස ලැම්බඩා නොවේ. 2) නැත, x = 5 ලැම්බඩා වලට දේශීය වේ (පිටත විෂය පථයේ විචල්‍ය x ට සමාන නමක් ඇති අගයක් අල්ලා ගැනීම), ඉන්පසු x + 2 = 5 + 2 ආපසු ලබා දෙනු ලැබේ. පිටත විචල්‍යය x නැවත පැවරීම සිදුවන්නේ r:, r = &x; r += 2;නමුත් මෙය සිදුවන්නේ 4 හි මුල් අගයට ය.
වී

169

ලැම්බඩා ප්‍රකාශන සාමාන්‍යයෙන් ඇල්ගොරිතම සංයුක්ත කිරීම සඳහා භාවිතා කරනු ලබන අතර එමඟින් ඒවා වෙනත් ශ්‍රිතයකට යොමු කළ හැකිය. කෙසේ වෙතත්, නිර්වචනය මත වහාම ලැම්බඩාවක් ක්‍රියාත්මක කළ හැකිය :

[&](){ ...your code... }(); // immediately executed lambda expression

ක්‍රියාකාරී ලෙස සමාන වේ

{ ...your code... } // simple code block

මෙය ලැම්බඩා ප්‍රකාශන සංකීර්ණ කාර්යයන් නැවත ප්‍රතිනිර්මාණය කිරීම සඳහා ප්‍රබල මෙවලමක් බවට පත් කරයි . ඉහත දැක්වෙන පරිදි ලැම්බඩා ශ්‍රිතයක කේත කොටසක් ඔතා ඔබ ආරම්භ කරන්න. පැහැදිලි පරාමිතිකරණ ක්‍රියාවලිය පසුව එක් එක් පියවරෙන් පසු අතරමැදි පරීක්ෂණ මගින් ක්‍රමයෙන් සිදු කළ හැකිය. ඔබ කේත-කොටස සම්පූර්ණයෙන් පරාමිතිකරණය කළ පසු (ඉවත් කිරීමෙන් පෙන්නුම් කරන පරිදි &), ඔබට කේතය බාහිර ස්ථානයකට ගෙන ගොස් එය සාමාන්‍ය කාර්යයක් බවට පත් කළ හැකිය.

ඒ හා සමානව, ඇල්ගොරිතමයක ප්‍රති result ලය මත පදනම්ව විචල්‍යයන් ආරම්භ කිරීම සඳහා ඔබට ලැම්බඩා ප්‍රකාශන භාවිතා කළ හැකිය ...

int a = []( int b ){ int r=1; while (b>0) r*=b--; return r; }(5); // 5!

ලෙස ඔබගේ වැඩසටහන තර්ක කොටස් කරන ක්රමයක් , ඔබ පවා එය එය ප්රයෝජනවත් තවත් ලැම්ඩා ප්රකාශනය කිරීමට තර්කයක් ලෙස ලැම්ඩා ප්රකාශනය සම්මත කිරීමට ඔබට සිතෙන්න පුළුවන් ...

[&]( std::function<void()> algorithm ) // wrapper section
   {
   ...your wrapper code...
   algorithm();
   ...your wrapper code...
   }
([&]() // algorithm section
   {
   ...your algorithm code...
   });

ලැම්බඩා ප්‍රකාශන මඟින් නම් කරන ලද කැදැලි ශ්‍රිත නිර්මාණය කිරීමට ඔබට ඉඩ සලසයි , එය අනුපිටපත් තර්කනය මග හැරීමට පහසු ක්‍රමයක් විය හැකිය. සුළු නොවන ශ්‍රිතයක් වෙනත් ශ්‍රිතයකට පරාමිතියක් ලෙස සම්මත කිරීමේදී නම් කරන ලද ලැම්බඩාස් භාවිතා කිරීම ඇස්වලට ටිකක් පහසු වේ (නිර්නාමික ඉන්ලයින් ලැම්බඩා සමඟ සසඳන විට). සටහන: වක්‍රාකාර වරහනෙන් පසු අර්ධ සළකුණ අමතක නොකරන්න.

auto algorithm = [&]( double x, double m, double b ) -> double
   {
   return m*x+b;
   };

int a=algorithm(1,2,3), b=algorithm(4,5,6);

පසුකාලීන පැතිකඩ මඟින් ශ්‍රිත වස්තුව සඳහා සැලකිය යුතු ආරම්භක ඉහළින් හෙළි කරයි නම්, ඔබට මෙය සාමාන්‍ය ශ්‍රිතයක් ලෙස නැවත ලිවීමට තෝරා ගත හැකිය.


11
මෙම ප්‍රශ්නය මීට වසර 1.5 කට පෙර අසන ලද බවත් අවසාන ක්‍රියාකාරකම වසර 1 කට පමණ පෙර සිදු වූ බවත් ඔබ තේරුම් ගෙන තිබේද? කෙසේ වෙතත්, ඔබ මා මීට පෙර දැක නැති රසවත් අදහස් කිහිපයක් සඳහා දායක වේ!
Piotr99

7
එකවර නිර්වචනය කර ක්‍රියාත්මක කළ ඉඟියට ස්තූතියි! එය ifප්‍රකාශ සඳහා ප්‍රතිවිරෝධතාවක් ලෙස ක්‍රියා කරන බව සඳහන් කිරීම වටී යැයි මම සිතමි : if ([i]{ for (char j : i) if (!isspace(j)) return false ; return true ; }()) // i is all whitespace, උපකල්පනය iකිරීමstd::string
බ්ලැක් ලයිට් දිලිසෙන

74
එබැවින් පහත දැක්වෙන්නේ නීතිමය ප්‍රකාශනයකි : [](){}();.
බ්‍රෙන්ට් බ්‍රැඩ්බර්න්

8
අහ්! පයිතන්ගේ (lambda: None)()වාක්‍ය ඛණ්ඩය ඊට වඩා පැහැදිලි ය.
dan04

9
ob නොබාර් - ඔබ හරි, මම වැරදියට ටයිප් කළා. මෙය නීත්‍යානුකූලයි (මම මෙවර එය අත්හදා main() {{{{((([](){{}}())));}}}}
බැලුවෙමි

38

පිළිතුරු

ප්‍ර: සී ++ 11 හි ලැම්බඩා ප්‍රකාශනය යනු කුමක්ද?

පිළිතුර: කබාය යටතේ, එය අධි බර පැටවීමේ ක්‍රියාකරු () const සහිත ස්වයංක්‍රීය උත්පාදක පන්තියක වස්තුවයි . එවැනි වස්තුවක් වසා දැමීම ලෙස හැඳින්වෙන අතර එය සම්පාදකයා විසින් නිර්මාණය කරනු ලැබේ. මෙම 'වසා දැමීමේ' සංකල්පය C ++ 11 හි බන්ධන සංකල්පය සමඟ සමීප වේ. නමුත් ලැම්බඩාස් සාමාන්‍යයෙන් වඩා හොඳ කේත ජනනය කරයි. සහ වසා දැමීම් හරහා කෙරෙන ඇමතුම් පූර්ණ පේළිගත කිරීමට ඉඩ දෙයි.

ප්‍ර: මම එකක් භාවිතා කරන්නේ කවදාද?

පිළිතුර: “සරල හා කුඩා තර්කනය” නිර්වචනය කිරීම සහ පෙර ප්‍රශ්නයෙන් සම්පාදක කාර්ය සාධනය විමසන්න. ඔබ ක්‍රියාකරු () තුළ සිටීමට අවශ්‍ය ප්‍රකාශන කිහිපයක් සම්පාදකයෙකුට ලබා දේ. අනෙක් සියලුම දේවල් සම්පාදකයා ඔබට ජනනය කරනු ඇත.

ප්‍රශ්නය: ඔවුන් හඳුන්වාදීමට පෙර කළ නොහැකි වූ ගැටලුව කුමක්ද?

පිළිතුර : එය අභිරුචි එකතු කිරීම්, උපසිරැසි මෙහෙයුම් සඳහා කාර්යයන් වෙනුවට ක්‍රියාකරුවන් අධික ලෙස පැටවීම වැනි සින්ටැක්ස් සීනි වර්ගයකි ... නමුත් සමහර පංතිවලට සැබෑ තර්කනයේ පේළි 1-3 ක් එතීමට අනවශ්‍ය කේත පේළි කිහිපයක් ඉතිරි කරයි, සහ යනාදිය! සමහර ඉංජිනේරුවන් සිතන්නේ රේඛා ගණන කුඩා නම් එහි දෝෂ ඇතිවීමට ඇති ඉඩකඩ අඩු බවයි (මමත් එසේ සිතමි)

භාවිතයේ උදාහරණය

auto x = [=](int arg1){printf("%i", arg1); };
void(*f)(int) = x;
f(1);
x(1);

ලැම්බඩාස් පිළිබඳ අමතර කරුණු, ප්‍රශ්න වලින් ආවරණය නොවේ. ඔබ උනන්දුවක් නොදක්වන්නේ නම් මෙම කොටස නොසලකා හරින්න

1. අල්ලා ගත් අගයන්. අල්ලා ගැනීමට ඔබට කළ හැකි දේ

1.1. ලැම්බඩාස් හි ස්ථිතික ගබඩා කාලය සහිත විචල්‍යයක් ඔබට යොමු කළ හැකිය. ඔවුන් සියල්ලන්ම අල්ලා ගනු ලැබේ.

1.2. "අගය අනුව" අල්ලා ගැනීමේ අගයන් සඳහා ඔබට ලැම්බඩා භාවිතා කළ හැකිය. එවැනි අවස්ථාවකදී අල්ලා ගන්නා ලද විචල්‍යයන් ශ්‍රිත වස්තුවට (වසා දැමීම) පිටපත් කරනු ලැබේ.

[captureVar1,captureVar2](int arg1){}

1.3. ඔබට යොමු විය හැකිය. & - මෙම සන්දර්භය තුළ යොමු දැක්වීමක් මිස දර්ශකයන් නොවේ.

   [&captureVar1,&captureVar2](int arg1){}

1.4. සියලු ස්ථිතික නොවන විචල්‍යයන් අගය අනුව හෝ යොමු කිරීම මගින් ග්‍රහණය කර ගැනීම සඳහා අංකනය පවතී

  [=](int arg1){} // capture all not-static vars by value

  [&](int arg1){} // capture all not-static vars by reference

1.5. සියලු ස්ථිතික නොවන විචල්‍යයන් අගය අනුව ග්‍රහණය කර ගැනීම සඳහා අංකනය පවතී, නැතහොත් යොමු කිරීම සහ smth නියම කිරීම. තවත්. උදාහරණ: ස්ථිතික නොවන සියලු විචල්‍යයන් අගය අනුව ග්‍රහණය කරගන්න

[=,&Param2](int arg1){} 

සියලු ස්ථිතික නොවන විචල්‍යයන් යොමු කිරීමෙන් අල්ලා ගන්න, නමුත් අගය ග්‍රහණය කර ගැනීම Param2

[&,Param2](int arg1){} 

2. ආපසු වර්ගය අඩු කිරීම

2.1. ලැම්බඩා එක් ප්‍රකාශනයක් නම් ලැම්බඩා ආපසු පැමිණීමේ වර්ගය අඩු කළ හැකිය. නැතහොත් ඔබට එය පැහැදිලිව සඳහන් කළ හැකිය.

[=](int arg1)->trailing_return_type{return trailing_return_type();}

ලැම්බඩාට වඩා වැඩි ප්‍රකාශනයක් තිබේ නම්, ආපසු එන වර්ගය පසුපස වර්ගය නියම කළ යුතුය. එසේම, ස්වයංක්‍රීය ශ්‍රිත සහ සාමාජික ක්‍රියාකාරකම් සඳහා සමාන සින්ටැක්ස් යෙදිය හැකිය

3. අල්ලා ගත් අගයන්. ඔබට අල්ලා ගත නොහැකි දේ

3.1. ඔබට ග්‍රහණය කරගත හැක්කේ දේශීය විචල්‍යයන් මිස වස්තුවෙහි සාමාජික විචල්‍යය නොවේ.

4. පරිවර්තනයන්

4.1 !! ලැම්බඩා යනු ශ්‍රිත දර්ශකයක් නොවන අතර එය නිර්නාමික ශ්‍රිතයක් නොවේ, නමුත් ග්‍රහණයෙන් අඩු ලැම්බඩාස් ව්‍යංගයෙන් ශ්‍රිත දර්ශකයක් බවට පරිවර්තනය කළ හැකිය.

ps

  1. ලැම්බඩා ව්‍යාකරණ තොරතුරු පිළිබඳ වැඩි විස්තර ක්‍රමලේඛන භාෂාව සඳහා වන වැඩ කෙටුම්පත C ++ # 337, 2012-01-16, 5.1.2. ලැම්බඩා ප්‍රකාශන, පි .88

  2. C ++ 14 හි "init capture" ලෙස නම් කර ඇති අතිරේක අංගය එකතු කර ඇත. සංවෘත දත්ත සාමාජිකයින්ගේ අත්තනෝමතික ලෙස ප්‍රකාශ කිරීමට එය ඉඩ දෙයි:

    auto toFloat = [](int value) { return float(value);};
    auto interpolate = [min = toFloat(0), max = toFloat(255)](int value)->float { return (value - min) / (max - min);};
    

මෙය [&,=Param2](int arg1){}වලංගු වාක්‍ය ඛණ්ඩයක් ලෙස නොපෙනේ. නිවැරදි පෝරමය වනුයේ[&,Param2](int arg1){}
GetFree

ස්තූතියි. මුලින්ම මම මේ ස්නිපටය සම්පාදනය කිරීමට උත්සාහ කළෙමි. අල්ලා ගැනීමේ ලැයිස්තුවේ ඉඩදිය හැකි විකරණකාරකවල අමුතු ඇසෙමෙට්‍රි ලෙස පෙනේ // g ++ -std = c ++ 11 main.cpp -o test_bin; ./test_bin # ඇතුළත් කරන්න <stdio.h> int main () {#if 1 {int param = 0; auto f = [=, & param] (int arg1) විකෘති {param = arg1;}; f (111); printf ("% i \ n", පාරම්); } #endif #if 0 {int param = 0; auto f = [&, = param] (int arg1) විකෘති {param = arg1;}; f (111); printf ("% i \ n", පාරම්); end #endif return 0; }
bruziuz

අදහස් දැක්වීමේදී සහය නොදක්වන නව පේළිය පෙනේ. ඉන්පසු මම 5.1.2 ලැම්බඩා ප්‍රකාශන විවෘත කළෙමි, පි .88, “වැඩ කරන කෙටුම්පත, ක්‍රමලේඛන භාෂාව සඳහා ප්‍රමිතිය සී ++”, වට්ටම් අංකය: # 337, 2012-01-16. ව්‍යාකරණ වාක්‍ය ඛණ්ඩය දෙස බැලීය. ඔබ හරි. "= Arg" හරහා අල්ලා ගැනීම වැනි දෙයක් නොමැත
bruziuz

ලොකු ස්තූතියි, එය විස්තරයෙන් සවි කර ඇති අතර ඒ සඳහා නව දැනුම ලබා ගන්න.
bruziuz

16

ලැම්බඩා ශ්‍රිතයක් යනු ඔබ පේළියේ නිර්මාණය කරන නිර්නාමික ශ්‍රිතයකි. සමහරු පැහැදිලි කර ඇති පරිදි එයට විචල්‍යයන් ග්‍රහණය කරගත හැකිය, (උදා: http://www.stroustrup.com/C++11FAQ.html#lambda ) නමුත් යම් සීමාවන් තිබේ. උදාහරණයක් ලෙස, මේ වගේ ඇමතුම් ආපසු අතුරු මුහුණතක් තිබේ නම්,

void apply(void (*f)(int)) {
    f(10);
    f(20);
    f(30);
}

පහත අයදුම් කිරීම සඳහා සම්මත කළ ආකාරයටම භාවිතා කිරීමට ඔබට එම ස්ථානයේදීම ශ්‍රිතයක් ලිවිය හැකිය:

int col=0;
void output() {
    apply([](int data) {
        cout << data << ((++col % 10) ? ' ' : '\n');
    });
}

නමුත් ඔබට මෙය කළ නොහැක:

void output(int n) {
    int col=0;
    apply([&col,n](int data) {
        cout << data << ((++col % 10) ? ' ' : '\n');
    });
}

C ++ 11 ප්‍රමිතියේ සීමාවන් නිසා. ඔබට ග්‍රහණයන් භාවිතා කිරීමට අවශ්‍ය නම්, ඔබ පුස්තකාලය මත විශ්වාසය තැබිය යුතුය

#include <functional> 

(හෝ එය වක්‍රව ලබා ගැනීම සඳහා ඇල්ගොරිතම වැනි වෙනත් STL පුස්තකාලයක්) ඉන්පසු සාමාන්‍ය ශ්‍රිතයන් මෙවැනි පරාමිතීන් ලෙස සම්මත කරනවා වෙනුවට std :: function සමඟ වැඩ කරන්න:

#include <functional>
void apply(std::function<void(int)> f) {
    f(10);
    f(20);
    f(30);
}
void output(int width) {
    int col;
    apply([width,&col](int data) {
        cout << data << ((++col % width) ? ' ' : '\n');
    });
}

1
හේතුව, ලැම්බඩා ග්‍රහණය කරගත නොහැකි නම් පමණක් ශ්‍රිත දර්ශකයක් බවට පරිවර්තනය කළ හැකිය. නම් applyවූ functor පිළිගත් සැකිල්ලක් විය, ඒක වැඩ කරනවා
sp2danny

1
නමුත් ගැටළුව වන්නේ අයදුම් කිරීම දැනට පවතින අතුරු මුහුණතක් නම්, එය පැරණි පැරණි ශ්‍රිතයකට වඩා වෙනස් ලෙස ප්‍රකාශ කිරීමේ සුඛෝපභෝගී බව ඔබට නොතිබිය හැකිය. එවැනි ලැම්බඩා ප්‍රකාශනයක් ක්‍රියාත්මක කරන සෑම අවස්ථාවකම සරල පැරණි ශ්‍රිතයක නව අවස්ථාවක් ජනනය කිරීමට ඉඩ සැලසෙන පරිදි ප්‍රමිතිය නිර්මාණය කළ හැකි අතර ග්‍රහණය කරන ලද විචල්‍යයන් සඳහා දෘඩ කේතනය කරන ලද යොමු කිරීම් ද ඇත. සම්පාදනය කරන වේලාවේදී ලැම්බඩා ශ්‍රිතයක් ජනනය වන බව පෙනේ. වෙනත් ප්‍රතිවිපාක ද ඇත. උදා: ඔබ ස්ථිතික විචල්‍යයක් ප්‍රකාශ කරන්නේ නම්, ඔබ ලැම්බඩා ප්‍රකාශනය නැවත ඇගයීමට ලක් කළත්, ඔබට නව ස්ථිතික විචල්‍යයක් නොලැබේ.
ටෙඩ්

1
ශ්‍රිත දර්ශකය බොහෝ විට සුරැකීමට අදහස් කරන අතර ලැම්බඩාස් ග්‍රහණය කරගත හැකිය. ග්‍රහණයට වඩා අඩු ලැම්බඩස් පමණක් ක්‍රියාකාරී ලක්ෂ්‍ය බවට පරිවර්තනය කිරීම සැලසුම්
කිරීමෙනි

1
එකම හේතුව නිසා දෙපැත්තෙන්ම විචලනය වන තොග විචල්‍යයන් පිළිබඳව ඔබ තවමත් අවධානය යොමු කළ යුතුය. Blogs.msdn.com/b/nativeconcurrency/archive/2012/01/29/ බලන්න. ප්‍රතිදානය හා අයදුම් කිරීම සමඟ මා ලියූ උදාහරණය ලියා ඇති අතර ඒ වෙනුවට ක්‍රියාකාරී දර්ශකයන්ට ඉඩ දී භාවිතා කළ හොත් ඒවා ක්‍රියාත්මක වනු ඇත. අයදුම්පත්රයේ සියලුම ඇමතුම් අවසන් වූ පසු තීරුව වෙන් කර ඇත. පවතින යෙදුම් අතුරුමුහුණත භාවිතා කර වැඩ කිරීමට මෙම කේතය නැවත ලියන්නේ කෙසේද? ඔබ අවසන් වන්නේ ගෝලීය හෝ ස්ථිතික විචල්‍යයන් හෝ කේතයේ තවත් අපැහැදිලි පරිවර්තනයක් භාවිතා කිරීමටද?
ටෙඩ්

1
හෝ සමහර විට ඔබ සරලවම අදහස් කරන්නේ ලැම්බඩා ප්‍රකාශන අගයන් සහ එබැවින් තාවකාලික බවයි, නමුත් කේතය නියතව පවතී (සිංගල්ටන් / ස්ථිතික) එවිට අනාගතයේදී එය හැඳින්විය හැකිය. එවැනි අවස්ථාවකදී, සමහර විට ශ්‍රිතය එහි වෙන් කර ඇති ග්‍රහණයන් වෙන් කර ඇති තාක් කල් එය වෙන් කළ යුතුය. ඇත්ත වශයෙන්ම එය ශ්‍රිතයේ බොහෝ වෙනස්කම් ලූපයකින් වෙන් කර ඇත්නම් එය අවුල් සහගත විය හැකිය.
ටෙඩ්

12

lambda expressionC ++ Bjarne Stroustrup හි ***The C++ Programming Language***11 වන පරිච්ඡේදයේ ( ISBN-13: 978-0321563842 ) කතුවරයාගෙන් හොඳම පැහැදිලි කිරීමක් ලබා දී ඇත .

What is a lambda expression?

ලැම්ඩා ප්රකාශනය සමහර විට ද ලෙස සඳහන්, ලැම්ඩා ලෙස උත්සවයට හෝ (නොකඩවා වැරදි කතා, නමුත් ව්යවහාර) ලැම්ඩා , ක නිර්වචනය කිරීමෙන් සහ භාවිතා කිරීම සඳහා සරල අංකනය නිර්නාමික කාර්යය වස්තුවක් . ක්‍රියාකරු () සමඟ නම් කරන ලද පංතියක් නිර්වචනය කරනවා වෙනුවට, පසුව එම පන්තියේ වස්තුවක් සාදා අවසානයේ එය ආයාචනා කිරීම වෙනුවට අපට කෙටිමං භාවිතා කළ හැකිය.

When would I use one?

ඇල්ගොරිතමයකට තර්කයක් ලෙස මෙහෙයුමක් සම්මත කිරීමට අවශ්‍ය විට මෙය විශේෂයෙන් ප්‍රයෝජනවත් වේ. චිත්‍රක පරිශීලක අතුරුමුහුණත් (සහ වෙනත් තැන්වල) සන්දර්භය තුළ, එවැනි මෙහෙයුම් බොහෝ විට ඇමතුම් ආපසු ලෙස හැඳින්වේ .

What class of problem do they solve that wasn't possible prior to their introduction?

මෙහිදී මම අනුමාන කරන්නේ ලැම්බඩා ප්‍රකාශනය සමඟ කරන සෑම ක්‍රියාවක්ම ඒවා නොමැතිව විසඳා ගත හැකි නමුත් බොහෝ කේත සහ වඩා විශාල සංකීර්ණතාවයකින්. ලැම්බඩා ප්‍රකාශනය මෙය ඔබේ කේතය ප්‍රශස්තිකරණය කිරීමේ ක්‍රමය සහ එය වඩාත් ආකර්ෂණීය කිරීමේ ක්‍රමයකි. Stroustup විසින් කනගාටුදායක ලෙස:

ප්‍රශස්තිකරණය කිරීමේ ways ලදායී ක්‍රම

Some examples

ලැම්බඩා ප්‍රකාශනය හරහා

void print_modulo(const vector<int>& v, ostream& os, int m) // output v[i] to os if v[i]%m==0
{
    for_each(begin(v),end(v),
        [&os,m](int x) { 
           if (x%m==0) os << x << '\n';
         });
}

හෝ ශ්‍රිතය හරහා

class Modulo_print {
         ostream& os; // members to hold the capture list int m;
     public:
         Modulo_print(ostream& s, int mm) :os(s), m(mm) {} 
         void operator()(int x) const
           { 
             if (x%m==0) os << x << '\n'; 
           }
};

හෝ පවා

void print_modulo(const vector<int>& v, ostream& os, int m) 
     // output v[i] to os if v[i]%m==0
{
    class Modulo_print {
        ostream& os; // members to hold the capture list
        int m; 
        public:
           Modulo_print (ostream& s, int mm) :os(s), m(mm) {}
           void operator()(int x) const
           { 
               if (x%m==0) os << x << '\n';
           }
     };
     for_each(begin(v),end(v),Modulo_print{os,m}); 
}

ඔබට අවශ්‍ය නම් ඔබට lambda expressionපහත පරිදි නම් කළ හැකිය :

void print_modulo(const vector<int>& v, ostream& os, int m)
    // output v[i] to os if v[i]%m==0
{
      auto Modulo_print = [&os,m] (int x) { if (x%m==0) os << x << '\n'; };
      for_each(begin(v),end(v),Modulo_print);
 }

නැතහොත් තවත් සරල නියැදියක් උපකල්පනය කරන්න

void TestFunctions::simpleLambda() {
    bool sensitive = true;
    std::vector<int> v = std::vector<int>({1,33,3,4,5,6,7});

    sort(v.begin(),v.end(),
         [sensitive](int x, int y) {
             printf("\n%i\n",  x < y);
             return sensitive ? x < y : abs(x) < abs(y);
         });


    printf("sorted");
    for_each(v.begin(), v.end(),
             [](int x) {
                 printf("x - %i;", x);
             }
             );
}

ඊළඟට ජනනය කරනු ඇත

0

1

0

1

0

1

0

1

0

1

0 sortedx - 1; x - 3; x - 4; x - 5; x - 6; x - 7; x - 33;

[]- මෙය අල්ලා ගැනීමේ ලැයිස්තුව හෝ lambda introducer: lambdasඔවුන්ගේ දේශීය පරිසරයට ප්‍රවේශයක් අවශ්‍ය නොවන්නේ නම් අපට එය භාවිතා කළ හැකිය.

පොතෙන් උපුටා ගැනීම:

ලැම්බඩා ප්‍රකාශනයක පළමු චරිතය සැමවිටම [ . ලැම්බඩා හඳුන්වාදියෙකුට විවිධ ස්වරූප ගත හැකිය:

[] : හිස් ග්‍රහණ ලැයිස්තුවක්. මෙයින් ගම්‍ය වන්නේ අවට සන්දර්භයෙන් දේශීය නම් කිසිවක් ලැම්බඩා ශරීරය තුළ භාවිතා කළ නොහැකි බවයි. එවැනි ලැම්බඩා ප්‍රකාශන සඳහා, දත්ත ලබා ගන්නේ තර්ක වලින් හෝ ස්ථානීය නොවන විචල්‍යයන්ගෙන් ය.

[&] : යොමු දැක්වීමෙන් ව්‍යංගයෙන් අල්ලා ගැනීම. සියලුම දේශීය නම් භාවිතා කළ හැකිය. සියලුම දේශීය විචල්‍යයන් ප්‍රවේශයෙන් ප්‍රවේශ වේ.

[=] : ව්‍යංගයෙන් අගය අනුව අල්ලා ගැනීම. සියලුම දේශීය නම් භාවිතා කළ හැකිය. සියලුම නම් වලින් ලැම්බඩා ප්‍රකාශනයේ ඇමතුම ලබා ගත් දේශීය විචල්‍යයන්ගේ පිටපත් වෙත යොමු වේ.

[අල්ලා ගැනීමේ ලැයිස්තුව]: පැහැදිලි ග්‍රහණය; ග්‍රහණය-ලැයිස්තුව යනු ග්‍රහණය කර ගත යුතු දේශීය විචල්‍යයන්ගේ නම් ලැයිස්තුවයි (එනම්, වස්තුව තුළ ගබඩා කර ඇත) යොමු හෝ අගය අනුව ය. පෙර සහ නම් සහිත විචල්‍යයන් යොමු කර ඇත. වෙනත් විචල්යයන් අගය මගින් අල්ලා ගනු ලැබේ. ග්‍රහණය කිරීමේ ලැයිස්තුවකට මෙය අඩංගු විය හැකි අතර පසුව එන ... මූලද්‍රව්‍ය ලෙස නම් කළ හැකිය.

[සහ, ග්රහණ-ලැයිස්තුව] : නිසැකයෙන්ම සඳහන් විසින් men- ලැයිස්තුවේ tioned නොවේ නම් සමග සියලු දේශීය විචල්ය අල්ලා. අල්ලා ගැනීමේ ලැයිස්තුවට මෙය අඩංගු විය හැකිය. ලැයිස්තුගත කර ඇති නම් & ට පෙර කළ නොහැක. ග්‍රහණ ලැයිස්තුවේ නම් කර ඇති විචල්‍යයන් අගය අනුව ග්‍රහණය කරගනු ලැබේ.

[=, ග්‍රහණය-ලැයිස්තුව] : ලැයිස්තුවේ සඳහන් කර නැති නම් සහිත සියලුම දේශීය විචල්‍යයන් අගය අනුව ව්‍යංගයෙන් ග්‍රහණය කරගන්න. අල්ලා ගැනීමේ ලැයිස්තුවේ මෙය අඩංගු විය නොහැක. ලැයිස්තුගත නම් වලට පෙර &. ග්‍රහණ ලැයිස්තුවේ නම් කර ඇති විචල්‍යයන් යොමු කිරීම මගින් ග්‍රහණය කරගනු ලැබේ.

ඊට පෙර සහ සැමවිටම දේශීය නාමයක් යොමු කිරීම මගින් ග්‍රහණය කර ඇති බවත්, කලින් සඳහන් නොකළ දේශීය නමක් සැමවිටම අගය මගින් ග්‍රහණය කර ගන්නා බවත් සලකන්න. ඇමතුම් පරිසරය තුළ විචල්‍යයන් වෙනස් කිරීමට ඉඩ දෙන්නේ යොමු කිරීම මඟින් පමණි.

Additional

Lambda expression ආකෘතිය

රූප විස්තරය මෙහි ඇතුළත් කරන්න

අමතර යොමු:


හොඳ පැහැදිලි කිරීමක්. පරාසය මත පදනම් වූ ලූප භාවිතා කරමින්, ඔබට ලැම්බඩාස් වළක්වා කේතය කෙටි කළ හැකියfor (int x : v) { if (x % m == 0) os << x << '\n';}
ඩියෙට්‍රික් බෝම්ගාටන්

3

C ++ හි ඇති ලැම්බඩා "ගමනේ දී ලබා ගත හැකි ශ්‍රිතය" ලෙස සලකනු ලැබේ. ඔව්, එය වචනයේ පරිසමාප්ත අර්ථයෙන්ම ගමනේ, ඔබ එය අර්ථ දක්වයි; එය භාවිතා කරන්න; සහ මව් ශ්‍රිත විෂය පථය අවසන් වන විට ලැම්බඩා ශ්‍රිතය නැති වී යයි.

c ++ එය c ++ 11 හි හඳුන්වා දුන් අතර සෑම කෙනෙකුම හැකි සෑම තැනකම මෙන් එය භාවිතා කිරීමට පටන් ගත්තේය. උදාහරණය සහ ලැම්බඩා යනු කුමක්ද යන්න මෙහි සොයාගත හැකිය https://en.cppreference.com/w/cpp/language/lambda

සෑම c ++ ක්‍රමලේඛකයෙකුටම දැන ගැනීමට අත්‍යවශ්‍ය නමුත් එහි නොමැති දේ මම විස්තර කරමි

ලැම්බඩා යනු සෑම තැනකම භාවිතා කිරීමට අදහස් නොකරන අතර සෑම ශ්‍රිතයක්ම ලැම්බඩා සමඟ ප්‍රතිස්ථාපනය කළ නොහැක. එය සාමාන්‍ය ක්‍රියාකාරිත්වයට සාපේක්ෂව වේගවත්ම නොවේ. එයට ලැම්බඩා විසින් හැසිරවිය යුතු පොදු කාර්යයක් තිබේ.

සමහර අවස්ථාවලදී පේළි ගණන අඩු කිරීමට එය නිසැකවම උපකාරී වනු ඇත. එය මූලික වශයෙන් කේතයේ කොටස සඳහා භාවිතා කළ හැකි අතර, එය එක් වරකට හෝ වැඩි ගණනක එකම ශ්‍රිතයකට කැඳවනු ලබන අතර එම කේත කැබැල්ල වෙනත් තැනක අවශ්‍ය නොවන අතර ඒ සඳහා ඔබට තනිවම ශ්‍රිතයක් නිර්මාණය කළ හැකිය.

පහත දැක්වෙන්නේ ලැම්බඩා සහ පසුබිමේ සිදුවන දේ පිළිබඳ මූලික උදාහරණයයි.

පරිශීලක කේතය:

int main()
{
  // Lambda & auto
  int member=10;
  auto endGame = [=](int a, int b){ return a+b+member;};

  endGame(4,5);

  return 0;

}

සම්පාදනය එය පුළුල් කරන්නේ කෙසේද:

int main()
{
  int member = 10;

  class __lambda_6_18
  {
    int member;
    public: 
    inline /*constexpr */ int operator()(int a, int b) const
    {
      return a + b + member;
    }

    public: __lambda_6_18(int _member)
    : member{_member}
    {}

  };

  __lambda_6_18 endGame = __lambda_6_18{member};
  endGame.operator()(4, 5);

  return 0;
}

ඔබට පෙනෙන පරිදි, ඔබ එය භාවිතා කරන විට එය කුමන ආකාරයේ පොදු කාර්යයක් එකතු කරයි. එබැවින් ඒවා සෑම තැනකම භාවිතා කිරීම හොඳ අදහසක් නොවේ. ඒවා අදාළ වන ස්ථානවල භාවිතා කළ හැකිය.


ඔව්, එය වචනයේ පරිසමාප්ත අර්ථයෙන්ම ගමනේ, ඔබ එය අර්ථ දක්වයි; එය භාවිතා කරන්න; සහ මව් ශ්‍රිත විෂය පථය අවසන් වන විට ලැම්බඩා ශ්‍රිතය නැති වී යයි .. ශ්‍රිතය ලැම්බඩා ඇමතුම වෙත ආපසු ලබා දෙන්නේ නම් කුමක් කළ යුතුද?
නවාස්

1
එය සාමාන්‍ය ක්‍රියාකාරිත්වයට සාපේක්ෂව වේගවත්ම නොවේ. එයට ලැම්බඩා විසින් හැසිරවිය යුතු පොදු කාර්යයක් තිබේ. ඔබ කවදා හෝ සත්ය ඕනෑම මිණුම් ලකුණක් ක්රියාත්මක මෙම ප්රකාශය සහාය ? ඊට පටහැනිව, ලැම්බඩා + සැකිලි බොහෝ විට හැකි වේගවත් කේත නිපදවයි.
නවාස්

2

හොඳයි, මම සොයාගත් එක් ප්‍රායෝගික භාවිතයක් වන්නේ බොයිලර් තහඩු කේතය අඩු කිරීමයි. උදාහරණයක් වශයෙන්:

void process_z_vec(vector<int>& vec)
{
  auto print_2d = [](const vector<int>& board, int bsize)
  {
    for(int i = 0; i<bsize; i++)
    {
      for(int j=0; j<bsize; j++)
      {
        cout << board[bsize*i+j] << " ";
      }
      cout << "\n";
    }
  };
  // Do sth with the vec.
  print_2d(vec,x_size);
  // Do sth else with the vec.
  print_2d(vec,y_size);
  //... 
}

ලැම්බඩා නොමැතිව, ඔබට විවිධ bsizeඅවස්ථා සඳහා යමක් කිරීමට අවශ්‍ය විය හැකිය . ඇත්ත වශයෙන්ම ඔබට ශ්‍රිතයක් නිර්මාණය කළ හැකි නමුත් ආත්ම පරිශීලක ශ්‍රිතයේ විෂය පථය තුළ භාවිතය සීමා කිරීමට ඔබට අවශ්‍ය නම් කුමක් කළ යුතුද? ලැම්බඩා වල ස්වභාවය මෙම අවශ්‍යතාවය සපුරාලන අතර මම එය එම අවස්ථාව සඳහා භාවිතා කරමි.


1

එය විසඳන එක් ගැටළුවක්: කොන්ස්ට් සාමාජිකයෙකු ආරම්භ කිරීම සඳහා ප්‍රතිදාන පරාමිති ශ්‍රිතයක් භාවිතා කරන ඉදිකිරීම්කරුගේ ඇමතුමක් සඳහා ලැම්බඩාට වඩා සරල කේතය

ප්‍රතිදාන පරාමිතියක් ලෙස එහි ප්‍රතිදානය ආපසු ලබා දීමෙන් එහි අගය නියම කරන ශ්‍රිතයකට ඇමතුමක් ලබා දීමෙන් ඔබේ පන්තියේ නියත සාමාජිකයෙකු ආරම්භ කළ හැකිය.


මෙය සරල ශ්‍රිතයකින් ද කළ හැකිය, එය ඔබ සම්බන්ධ කළ ප්‍රශ්නයට පිළිගත් පිළිතුර පවා කිරීමට යැයි කියනු ලැබේ.
සර්ගුයි
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.