【问题标题】:Functors and iteration trough vector函子和迭代槽向量
【发布时间】:2019-07-16 01:57:59
【问题描述】:

我正在尝试进入“现代”C++,因此我正在尝试学习如何正确使用函子,以及随后的 lambda。 我想我已经理解了它背后的基本原理,但是我很难理解如何从传递给我的算法的向量中获取任何元素。 所以,假设我希望创建一个长度为 N 的斐波那契数列...

struct Adder {
    int operator()(int a, int b) {return a+b;}
};
const int N = 10;

int main() {

    std::vector<int> vec = {0, 1};
    vec.resize(N);

    //Old Way
    for(int i = 2; i < vec.size(); i++) {
        vec[i] = vec[i-1] + vec[i-2];
    }

    std::transform(vec.begin(), vec.end(), vec.begin(), [](int i){return i*3;});    //single operator given to function, works

//    std::transform(vec.begin()+2, vec.end(), vec.begin(), /*here two calls are needed , for a and b operators*/);

    return 0;
}

基本上我的问题是如何激活struct Adder 中定义的函子?将两个运算符传递给他的正确方法是什么?

【问题讨论】:

  • 你想达到什么目的?将两个序列转换为一个序列?
  • @L.F.我希望得到与上面for loop 相同的效果。对std::transform 的非注释调用是一个简单的演示,说明了如何检索当前迭代器位置。我感兴趣的是如何检索不是vec[i],而是vec[i+a] 的任何元素,其中a 可以是正值和负值(具有明显的越界限制等)。

标签: c++ lambda functor


【解决方案1】:

Adder::operator() 应该是 const。并且您的 Adder 函子是不必要的。只需使用std::plus&lt;&gt;

从 C++17 开始,我们有了接受两个序列的 transform 重载。所以我们可以这样做:(如果需要,可以使用Adder{} 代替std::plus&lt;&gt;{}

std::transform(vec.begin(), vec.end() - 2, vec.begin() + 1, vec.begin() + 2, std::plus<>{});

最小示例:(live demo)

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

constexpr int N = 10;

int main()
{
    std::vector<int> vec{0, 1};
    vec.resize(N);

    std::transform(vec.begin(), vec.end() - 2, vec.begin() + 1, vec.begin() + 2, std::plus<>{});

    for (int x : vec)
        std::cout << x << " ";
    std::cout << "\n";
}

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2010-10-02
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2013-09-02
    相关资源
    最近更新 更多