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]
。
谢谢
答案 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表达式时 参数声明子句后面没有可变的。