2

我有一个仿函数,它创建了一组线性间隔的值。. .

//Linear spaced generator
struct gen_lin {
    float mi, inc;
public:
    gen_lin(float _mi=1.f, float _inc=1.f) : mi(_mi), inc(_inc){};
    float operator()() {
        return  mi+=inc;
    }
};

我可以用这样的值填充一个向量......

const size_t elements = 400;
std::vector<float> x(elements);
std::generate_n(x.begin(), elements, gen_lin(10.f,5.f) );

现在,我可以使用像这样的 lambda 轻松地将其转换为对数刻度......

auto lin = gen_lin(10.f,5.f);
std::generate_n(x.begin(), elements, [&](){return logf(lin());} );

但是当我尝试将它全部压缩到一行时,向量完全被 logf(10.) 的值填充。

std::generate_n(x.begin(), elements, [](){return logf(  gen_lin(10.f,5.f)() );} );

为什么,是否可以调整我的最后一行代码以使其工作?

4

3 回答 3

2

这样,您将创建一个 gen_lin 对象,并多次使用它:

auto lin = gen_lin(10.f,5.f);
std::generate_n(x.begin(), elements, [&](){return logf(lin());} );

有了这个,你正在创建几个 gen_lin 对象:

std::generate_n(x.begin(), elements, [](){return logf(  gen_lin(10.f,5.f)() );} );

每次创建新的 gen_lin 对象时,都会重置当前值。

于 2012-12-21T02:14:58.340 回答
2

在第一种情况下:

auto lin = gen_lin(10.f,5.f);
std::generate_n(x.begin(), elements, [&](){return logf(lin());} );

您有一个持久gen_lin对象 ,lin每次调用 lambda 都会更新它。但是对于你的单线,你只是gen_lin在每次调用 lambda 时创建新对象,获取它返回的第一个值,然后将对象扔掉。因为它是一个新对象,用相同的常量值初始化,所以每次都会给你相同的值。

于 2012-12-21T02:15:26.463 回答
1

在第二种情况下,每个 lamdas 调用都会创建一个新的仿函数实例。

像 bind 这样的东西可能会解决你的问题。让 lambda 将您的仿函数作为参数并使用 bind 将公共实例附加到该参数?

或者使用任何风格的组合函子。

于 2012-12-21T02:19:44.893 回答