c++ - Lambda:为什么按值捕获的值是常量,但按引用捕获的值不是?

标签 c++ c++11 lambda constants capture

为什么按值捕获的值是常量,但按引用捕获的对象不是:

int a;

auto compile_error = [=]()
{
  a = 1;
}
auto compiles_ok = [&]()
{
  a = 1;
}

对我来说这似乎不合逻辑,但它似乎是标准?特别是因为对捕获值的不必要修改可能是一个恼人的错误,但后果仅限于 lambda 范围的可能性很高,而通过引用捕获的对象的不必要修改通常会导致更严重的影响。

那么为什么不默认通过 const 引用捕获呢?或者至少支持 [const &] 和 [&]?这样设计的原因是什么?

作为解决方法,您可能应该使用 std::cref 包装的按值捕获的 const 引用?

最佳答案

假设您正在按值捕获指针。指针本身是 const,但访问它指向的对象不是。

int i = 0;
int* p = &i;
auto l = [=]{ ++*p; };
l();
std::cout << i << std::endl;  // outputs 1

这个 lambda 等同于:

struct lambda {
    int* p;
    lambda(int* p_) : p(p_) {}
    void operator()() const { ++*p; }
};

operator()() 上的 const 使用 p 等同于将其声明为:

int* const p;

引用也会发生类似的事情。引用本身是“const”(在引号中,因为不能重新设置引用),但访问它引用的对象不是。

关于c++ - Lambda:为什么按值捕获的值是常量,但按引用捕获的值不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16764153/

相关文章:

c++ - 将数据从构造函数传递到成员函数

c++ - Linux 的 COleDateTime 替代品

c++ - 将 C++ 中的数据保存到用户无法访问的文件中?

c++ - 正确使用右值引用作为参数

c++ - 静态链接 C++ OpenCV

c# - Action<T> 与虚拟方法

c# - Include 内使用的 Lambda 表达式无效

Java 8 将 Map<Integer, List<String>> 转换为 Map<String, List<Integer>>

c++ - MFC 中的抽象基类是否需要 DECLARE_DYNAMIC?

c++ - 含义 std::mutex unlock 与 lock 同步以重新获取