使用for_each和lambda时出错

时间:2017-03-17 06:37:27

标签: c++ c++11 lambda

我正在尝试使用lambda函数解决一个简单的Fibonacci问题,但我遇到了这个错误,我无法解决它。

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>


using namespace std;

int main()
{
    string str;
    auto N{0};
    auto i{0};

    cout<<"Digite o valor de N desejado: ";
    getline(cin,str); //pega linha
    stringstream(str) >> N;

    if (N == 0){cout<<0;}
    else if (N == 1){cout<<1;}
    else
    {
        vector<int> v{0,1}; //cria vetor v

        for_each(v.begin(),N,
            [&](){
            v.push_back(v[i]+v[i+1]);
            i++;
        });

        i = 0;

        for_each(v.begin(),N,
            [&](){
            cout<<v[i];
            i++;
            });
    }

    return 0;
}

错误如下:

quest1.cpp: In function ‘int main()’: quest1.cpp:30:4: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’    });
    ^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
                 from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
     for_each(_InputIterator __first, _InputIterator __last, _Function __f)
     ^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note:   template argument deduction/substitution failed: quest1.cpp:30:4: note:   deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’)    });
    ^ quest1.cpp:38:5: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’
    });
     ^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
                 from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
     for_each(_InputIterator __first, _InputIterator __last, _Function __f)
     ^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note:   template argument deduction/substitution failed: quest1.cpp:38:5: note:   deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’)
    });

3 个答案:

答案 0 :(得分:1)

std::for_each需要(因为错误试图告诉你)迭代器在哪里开始循环,迭代器在哪里结束。但是,您正在传递迭代器和int,它们是#34;冲突类型&#34;。如果你想循环遍历整个向量,请执行以下操作:

std::vector<int> v{1, 2, 3};
std::for_each(v.begin(), // start at the front
              v.end(),   // loop over each element
              [&] (int& i) {
                i++;
              });

如果您只需要遍历矢量的一部分那么

std::vector<int> v{1, 2, 3};
std::for_each(v.begin(),       // start at the front
              v.begin() + 2,   // loop over the first two elements
              [&] (int& i) {
                i++;
              });

答案 1 :(得分:1)

您的代码中存在两个问题。一个(已经被其他答案覆盖),你将迭代次数作为第二个参数传递给std::for_each,但它实际上需要一个结束迭代器。 std::for_each(a, b, f)旨在从迭代器a迭代到迭代器b,并在该范围内的每个元素上调用f

第二个问题更为基础:如果在迭代时修改向量,则会得到未定义行为,因为任何修改操作都会使向量的所有迭代器无效。

查看你的代码,似乎你想要第一个循环到正常的计数循环而不是迭代容器。第二个循环可以使用for_each和lambda:

完成
vector<int> v{0,1};

for (int i = 0; i < N; ++i) {
  v.push_back(v[i] + v[i+1]);
}

for_each(v.begin(), v.end(),
  [](int element) {
    cout << element;
  }
);

请注意for_each中使用的仿函数不是nullary:算法会将元素传递给它。

或者,可以在没有lambdas的情况下实现打印功能:

copy(v.begin(), v.end(), ostream_iterator<int>(cout));

或者,如果您希望保持循环,也可以使用基于范围的for循环而不是for_each。代码将更短,[主观]更容易阅读[/主观]:

for (int elem : v) {
  std::cout << elem;
}

答案 2 :(得分:0)

您没有正确使用for_each功能。 C ++不知道您正在使用的签名。请参阅文档,例如for_each

编译器就是这么说的。您调用的for_each的第二个参数是int&类型,但签名是for_each(InputIterator, InputIterator, Function)而不是for_each(InputIterator, int&, Function),因此无法编译。