【问题标题】:Capture by value with reference parameter modifies captured variable outside expression?使用引用参数按值捕获修改表达式外部捕获的变量?
【发布时间】:2017-06-19 01:57:51
【问题描述】:

当捕获 hello 作为参考时,我希望能够在我的 lambda 函数之外修改 hello,但以下代码以相同的 hello 结尾。

#include <iostream>
#include <algorithm>
using namespace std;

int main(){
  char hello[] = {"Hello, World!"};

  auto up = [&, hello] (char c) {
      if (!isupper(c))
      {
          c = toupper(c);
      }
  };
  for_each(hello, hello + sizeof(hello), up);

  cout<<hello<<endl;
}

Hello, World!

当使用 c 作为参考参数按值传递 hello 时,我得到了预期的结果。

#include <iostream>
#include <algorithm>
using namespace std;

int main(){
  char hello[] = {"Hello, World!"};

  auto up = [hello] (char& c) {
      if (!isupper(c))
      {
          c = toupper(c);
      }
  };
  for_each(hello, hello + sizeof(hello), up);

  cout<<hello<<endl;
}

cout<<hello<<endl;

HELLO, WORLD!

我的理解是当 hello 被 value 捕获时,up 会得到一个本地的 hello 副本。暗示 c 是否为引用 hello 不会被修改。但在我的示例中,c 充当对 hello 的非本地副本的引用。我觉得我好像遗漏了一些基本的参考。

【问题讨论】:

  • 您的 lambda 表达式都不使用捕获的实体。
  • 你对 lambda 捕获的理解是完全错误的。您展示的两个 lambda 表达式都没有使用 hello,因此无论您是通过值还是通过引用来捕获它(在这两种情况下,您都是通过值来捕获它)绝对没有区别,无论如何。您的 lambdas 唯一需要捕获的是您的 lambdas 引用的对象。您的 lambda 表达式中没有任何内容引用 hello,因此您捕获 hello 的方式会有所不同。
  • 顺便说一句,没有理由检查!isupper(c),因为toupper 会为您检查,如果它不是小写字母,则简单地返回未修改的字符。

标签: c++ c++11 lambda


【解决方案1】:

编译后,您的 lambda 表达式实际上并未捕获任何内容,因此您不妨编写:

auto up = [] (char c) {
  if (!isupper(c))
  {
      c = toupper(c);
  }
};

但是,即使您确实使用了[&amp;],您认为编译器如何知道chello 的一部分? c 不能轻松地成为goodbye 的一部分吗?

您可以认为使用&amp;c 告诉编译器c 属于哪个数组。

另外,您使用的是 C++,不建议使用这些原始数组。这也许是更好的方法:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main(){
  std::string hello = {{"Hello, World!"}};

  auto up = [hello] (char& c) { c = toupper(c); };
  for_each(hello.begin(), hello.end(), up);

  cout<<hello<<endl;
}

【讨论】:

  • 我对捕获组的假设过多。正如上面的 cmets 所说,我没有在我的表达中使用它们。我忽略了 for_each 将 c 传递到 up 的句柄。
猜你喜欢
  • 2012-06-18
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
相关资源
最近更新 更多