4

所以我试图测试一个 lambda 在它使用的范围内访问局部变量,大致基于 Bjarne 在 C++0x FAQS 页面上的一个简单示例: http ://www2.research.att.com/ ~bs/C++0xFAQ.html#lambda

当我尝试这个简单的测试代码时:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//Test std::fill() with C++0x lambda and local var
void f (int v) { 
    vector<int> indices(v);
    int count = 0;
    fill(indices.begin(), indices.end(), [&count]() {
        return ++count;
    });

    //output test indices
    for (auto x : indices) {
        cout << x << endl;
    }
}

int main() {
    f(50);
}

我得到错误:

required from 'void std::fill(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >, _Tp = f(int)::<lambda()>]'

我假设这个 errmsg 表明 std::fill() 签名需要一个 const Type& 才能用于新的值元素分配。

但是,如果我能够为此目的使用 fill(),如 Bjarne 的示例所示,我不需要在 lambda 捕获子句中使用引用 '[&count]' 来重新分配原始通过'return ++count;'索引元素值和递增计数var lambda 语句块?

我承认我还不太了解这些 lambda!:)

4

3 回答 3

16

Bjarne 的示例无法编译。它无法编译,除非它们std::fill在 C++0x 中定义不同。也许它来自一个std::fill可以接受函数的概念版本,但它的实际版本(根据 N3242 的第 25.1 节)接受一个对象,而不是一个函数。它将该对象复制到列表的每个元素中。这就是那个人正在尝试做的事情。

您正在寻找的功能是std::generate.

于 2011-07-10T07:11:56.913 回答
1

试试这个:

for_each(indices.begin(), indices.end(), [&count](int& it) 
{        
    it = ++count;    
});

it当前是向量的迭代内容,并且是通过引用来的。

于 2011-07-10T13:09:22.247 回答
1

我希望添加“更新”样式的答案是可以的,以使未来可能有同样问题的读者受益。请让我知道,因为我是新来的。

所以,这是我想要做的代码的最终修改形式:

#include <iostream>
#include <vector>
#include <algorithm>

//Overwrite a vector<int> with incrementing values, base-n.
void init_integers(std::vector<int>& ints, int base) {
    int index{ base };
    std::generate(ints.begin(), ints.end(), [&index]() {
        return index++;  //post-incr.
    });
}

//Default wrapper to overwrite a vector<int> 
// with incrementing values, base-0.
void init_integers(std::vector<int>& ints) {
    init_integers(ints, 0);
}

//Test lambda-based vector<int> initialization.
int main() {
    std::vector<int> indices( 50 );
    init_integers(indices);

    //test output loaded indices.
    for (auto x : indices) {
        std::cout << x << std::endl;
    }
}

感谢您提供有用的答案,我发现这是一种更简单的方法。从现在开始,我很可能将 lambdas 用于采用函数对象的算法!



更新 2:

基于 ildjarn 对上述原始帖子的评论:“请注意,此处的确切功能是由新的 C++0x 算法 - std::iota 实现的。”

经过测试,我将相应的代码修改为:

...
#include <numeric>

//Overwrite a vector<int> with incrementing values, base-n.
void init_integers(std::vector<int>& ints, int base) {
    std::iota(ints.begin(), ints.end(), base);
}
...

它工作正常。(“Iota”,s26.7.6,N3242)。

越简单和干净(虽然有点晦涩),越容易阅读——更重要的是——维护。

谢谢伊尔加恩!(尽管亲自经历这个过程以进一步了解 C++0x lambdas 是一个很好的练习!):) -Bud Alverson

于 2011-07-10T19:18:33.670 回答