• <small id='QLarm'></small><noframes id='QLarm'>

      <bdo id='QLarm'></bdo><ul id='QLarm'></ul>
    1. <legend id='QLarm'><style id='QLarm'><dir id='QLarm'><q id='QLarm'></q></dir></style></legend>

      1. <i id='QLarm'><tr id='QLarm'><dt id='QLarm'><q id='QLarm'><span id='QLarm'><b id='QLarm'><form id='QLarm'><ins id='QLarm'></ins><ul id='QLarm'></ul><sub id='QLarm'></sub></form><legend id='QLarm'></legend><bdo id='QLarm'><pre id='QLarm'><center id='QLarm'></center></pre></bdo></b><th id='QLarm'></th></span></q></dt></tr></i><div id='QLarm'><tfoot id='QLarm'></tfoot><dl id='QLarm'><fieldset id='QLarm'></fieldset></dl></div>

        <tfoot id='QLarm'></tfoot>

        C++11 lambda 返回 lambda

        时间:2023-10-05

        1. <legend id='eLeYZ'><style id='eLeYZ'><dir id='eLeYZ'><q id='eLeYZ'></q></dir></style></legend>
            • <bdo id='eLeYZ'></bdo><ul id='eLeYZ'></ul>

              • <tfoot id='eLeYZ'></tfoot>
                <i id='eLeYZ'><tr id='eLeYZ'><dt id='eLeYZ'><q id='eLeYZ'><span id='eLeYZ'><b id='eLeYZ'><form id='eLeYZ'><ins id='eLeYZ'></ins><ul id='eLeYZ'></ul><sub id='eLeYZ'></sub></form><legend id='eLeYZ'></legend><bdo id='eLeYZ'><pre id='eLeYZ'><center id='eLeYZ'></center></pre></bdo></b><th id='eLeYZ'></th></span></q></dt></tr></i><div id='eLeYZ'><tfoot id='eLeYZ'></tfoot><dl id='eLeYZ'><fieldset id='eLeYZ'></fieldset></dl></div>
                  <tbody id='eLeYZ'></tbody>

                <small id='eLeYZ'></small><noframes id='eLeYZ'>

                • 本文介绍了C++11 lambda 返回 lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  这段代码对于JS开发者来说并不是陌生的

                  this piece of code is not something unknown to JS developers

                  function get_counter()
                  {
                      return (
                          function() {
                              var c = 0;
                              return function() { return ++c; };
                          })();
                  }
                  

                  它基本上创建了一个,它创建了不同的枚举器.所以我想知道是否可以使用新的 lambda 语义在 C++11 中完成同样的事情?我最终写了这段 C++ 不幸的是不能编译!

                  it basically creates a which creates different enumerators. So I was wondering if same thing can be done in C++11 with new lambda semantics? I ended up writing this piece of C++ which unfortunately does not compile!

                  int main()
                  {
                      int c;
                      auto a = [](){
                          int c = 0;
                          return [&](){
                              cout << c++;
                          };
                      };
                      return 0;
                  }
                  

                  所以我想知道是否有解决方法可以编译它,如果有编译器如何使此代码正确运行?我的意思是它必须创建单独的枚举器,但它也应该收集垃圾(未使用的 c 变量).

                  so I was wondering if there is a workaround to get it compiled and if there is how can compiler make this code run correctly? I mean it has to create separate enumerators but it should also collect garbage (unused c variables).

                  顺便说一下,我使用的是 VS2012 编译器,它会生成此错误:

                  by the way I'm using VS2012 compiler and it generates this error:

                  Error   2   error C2440: 'return' : cannot convert from 'main::<lambda_10d109c73135f5c106ecbfa8ff6f4b6b>::()::<lambda_019decbc8d6cd29488ffec96883efe2a>' to 'void (__cdecl *)(void)'    c:usersalidocumentsvisual studio 2012projects	est	estmain.cpp   25  1   Test
                  

                  推荐答案

                  您的代码有一个错误,它包含一个悬空引用;c 引用将引用外部 lambda 中的局部变量,当外部 lambda 返回时该变量将被销毁.

                  Your code has a bug in that it contains a dangling reference; the c reference will refer to the local variable in the outer lambda, which will be destroyed when the outer lambda returns.

                  您应该使用 mutable 按值 lambda 捕获来编写它:

                  You should write it using a mutable by-value lambda capture:

                  auto a = []() {
                      int c = 0;
                      return [=]() mutable {
                          cout << c++;
                      };
                  };
                  

                  这依赖于后标准扩展,以允许在返回类型推导的 lambda 中使用多个语句;如果 lambda 包含多个语句,是否有理由不允许它推导出返回类型? 最简单的修复方法是提供一个参数,以便 lambda 只包含一个语句:

                  This relies on a post-standard extension to allow multiple statements in a return-type-deducing lambda; Is there a reason on not allowing lambdas to deduce the return type if it contains more than one statement? The easiest way to fix it is to supply a parameter so that the lambda contains only a single statement:

                  auto a = [](int c) {
                      return [=]() mutable {
                          cout << c++;
                      };
                  };
                  

                  不幸的是,lambdas 中不允许使用默认参数,因此您必须将其称为 a(0).或者,以可读性为代价,您可以使用嵌套的 lambda 调用:

                  Unfortunately default parameters aren't allowed in lambdas, so you'd have to call this as a(0). Alternatively at the cost of readability you could use a nested lambda call:

                  auto a = []() {
                      return ([](int c) {
                          return [=]() mutable {
                              cout << c++;
                          };
                      })(0);
                  };
                  

                  这种工作方式是,当 a 执行内部 lambda 时,会将所有引用的变量复制到其闭包类型的一个实例中,如下所示:

                  The way this works is that when a executes the inner lambda copies all the referenced variables into an instance of its closure type, which here would be something like:

                  struct inner_lambda {
                      int c;
                      void operator()() { cout << c++; }
                  };
                  

                  闭包类型的实例然后由外部 lambda 返回,并且可以被调用并在调用时修改它的 c 副本.

                  The instance of the closure type is then returned by the outer lambda, and can be invoked and will modify its copy of c when called.

                  总的来说,你的(固定的)代码被翻译成:

                  Overall, your (fixed) code is translated to:

                  struct outer_lambda {
                      // no closure
                      struct inner_lambda {
                          int c;    // by-value capture
                          // non-const because "mutable"
                          void operator()() { cout << c++; }
                      }
                      // const because non-"mutable"
                      inner_lambda operator()(int c) const {
                          return inner_lambda{c};
                      }
                  };
                  

                  如果您将 c 作为按引用捕获保留,则为:

                  If you left c as a by-reference capture, this would be:

                  struct outer_lambda {
                      // no closure
                      struct inner_lambda {
                          int &c;    // by-reference capture
                          void operator()() const { cout << c++; } // const, but can modify c
                      }
                      inner_lambda operator()(int c) const {
                          return inner_lambda{c};
                      }
                  };
                  

                  这里的 inner_lambda::c 是对局部参数变量 c 的悬空引用.

                  Here inner_lambda::c is a dangling reference to the local parameter variable c.

                  这篇关于C++11 lambda 返回 lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:轮廓 opencv:如何消除二值图像中的小轮廓 下一篇:Visual C++ - 内存泄漏检测

                  相关文章

                  最新文章

                • <tfoot id='oX5k0'></tfoot>
                  <i id='oX5k0'><tr id='oX5k0'><dt id='oX5k0'><q id='oX5k0'><span id='oX5k0'><b id='oX5k0'><form id='oX5k0'><ins id='oX5k0'></ins><ul id='oX5k0'></ul><sub id='oX5k0'></sub></form><legend id='oX5k0'></legend><bdo id='oX5k0'><pre id='oX5k0'><center id='oX5k0'></center></pre></bdo></b><th id='oX5k0'></th></span></q></dt></tr></i><div id='oX5k0'><tfoot id='oX5k0'></tfoot><dl id='oX5k0'><fieldset id='oX5k0'></fieldset></dl></div>
                    <bdo id='oX5k0'></bdo><ul id='oX5k0'></ul>
                • <legend id='oX5k0'><style id='oX5k0'><dir id='oX5k0'><q id='oX5k0'></q></dir></style></legend>

                    <small id='oX5k0'></small><noframes id='oX5k0'>