无法通过复制将数组地址传递给匿名函数

时间:2014-07-10 15:18:19

标签: c++ c++11

void F(int A[], int n) { // Correct
    int arr[3] = {0}; // A[..] in the range of 0-2
    for_each(A, A+n, [&arr](const int& num) -> void {
       ++arr[num];
    });
}

void F(int A[], int n) { // Wrong: b/c [arr] should be [&arr]
    int arr[3] = {0}; // A[..] in the range of 0-2
    for_each(A, A+n, [arr](const int& num) -> void {
       ++arr[num];
    });
}
  

错误:只读位置的增量'arr [((int)num)]'++ arr [num];

问题>为什么我看到上面的错误? 如果匿名函数需要修改值,则[]中的参数应以&为前缀。但是,在这里,我传入一个数组的地址。为什么我仍然需要使用[&arr]而不是[arr]

谢谢

2 个答案:

答案 0 :(得分:1)

数组不是指针。 arr不是指针,它是一个数组。标准中没有任何地方表示在lambda捕获上发生了数组到指针的转换。因此lambda不捕获指针,它通过值或引用捕获实际数组。由于按值捕获有效const,除非将lambda声明为mutable,否则您将收到错误。

换句话说,lambda的闭包类型将在[&arr]情况下拥有此数据成员:

int (&arr)[3];

[arr]案例中的数据成员:

int arr[3];

不要忘记,当声明lambda而没有mutable时,闭包operator()const成员函数:

auto operator() (const int& num) const -> void {
  // ... code
}

这意味着它无法修改按值捕获的数据成员。

答案 1 :(得分:1)

lambda将arr捕获为 const 。如果您希望能够修改阵列,则需要使用可变

void F(int A[], int n) { // Wrong: b/c [arr] should be [&arr]
    int arr[3] = {0}; // A[..] in the range of 0-2
    for_each(A, A+n,  [arr](const int& num) mutable -> void {
       ++arr[num];
    });
}

或者,更准确地说,lambda表达式就像没有 mutable 关键字的const函数:

  

5.1.2.5 lambda表达式的闭包类型具有公共内联函数   调用操作符(13.5.4),其参数和返回类型为   由lambda-expression的parameter-declaration-clause和   分别为trailing-return-type。这个函数调用运算符是   声明const(9.3.1)当且仅当lambda表达式时   参数声明子句后面没有可变的。