C++ &引用;“调用”没有匹配的函数;尝试对向量使用擦除功能时

C++ &引用;“调用”没有匹配的函数;尝试对向量使用擦除功能时,c++,algorithm,c++11,vector,erase,C++,Algorithm,C++11,Vector,Erase,我正在尝试使用擦除函数从向量中删除任何值为0的整数 void eliminateZeroes(std::vector<int> &answers){ auto i = answers.cbegin(); while(i != answers.cend()){ if(*i == 0){ i = answers.erase(i); }else{ i++; }

我正在尝试使用擦除函数从向量中删除任何值为0的整数

void eliminateZeroes(std::vector<int> &answers){
    auto i = answers.cbegin();
    while(i != answers.cend()){
        if(*i == 0){
            i = answers.erase(i);
        }else{
            i++;
        }

    }
void deliminateZeeroes(标准::向量和答案){
自动i=answers.cbegin();
而(i!=answers.cend()){
如果(*i==0){
i=答案。删除(i);
}否则{
i++;
}
}
我希望函数能从向量中删除任何值为0的项

错误消息:

/home/ec2-user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp: In function ‘void eliminateZeroes(std::vector<int>&)’:
/home/ec2-user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:32:36: error: no matching function for call to ‘std::vector<int>::erase(__gnu_cxx::__normal_iterator<const int*, std::vector<int> >&)’
                 i = answers.erase(i);
                                    ^
/home/ec2-user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:32:36: note: candidates are:
In file included from /usr/include/c++/4.8.5/vector:69:0,
                 from /home/ec2-user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:1:
/usr/include/c++/4.8.5/bits/vector.tcc:134:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8.5/bits/vector.tcc:134:5: note:   no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const int*, std::vector<int> >’ to ‘std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}’
/usr/include/c++/4.8.5/bits/vector.tcc:146:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8.5/bits/vector.tcc:146:5: note:   candidate expects 2 arguments, 1 provided
/home/ec2 user/environment/DP378-Havel_Hakimi_-\u Easy/main.cpp:在函数“void-eliminateZeroes(std::vector&)”中:
/home/ec2 user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:32:36:错误:调用“std::vector::erase(u gnu_cxx::u normal_iterator&)”时没有匹配的函数
i=答案。删除(i);
^
/home/ec2 user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:32:36:注:候选对象包括:
在/usr/include/c++/4.8.5/vector:69:0中包含的文件中,
from/home/ec2 user/environment/DP378-Havel_Hakimi_-_Easy/main.cpp:1:
/usr/include/c++/4.8.5/bits/vector.tcc:134:5:注:std::vector::迭代器std::vector::erase(std::vector::迭代器)[带Tp=int;Alloc=std::分配器;std::vector::迭代器=u gnu_cxx:u normal迭代器;typename std:vector\uBase::pointer=int*]
矢量::
^
/usr/include/c++/4.8.5/bits/vector.tcc:134:5:注意:参数1从“_gnu_cxx::_normal_iterator”到“std::vector::iterator{aka__gnu cxx:__normal_iterator}”没有已知的转换
/usr/include/c++/4.8.5/bits/vector.tcc:146:5:注:std::vector::迭代器std::vector::erase(std::vector::迭代器,std::vector::迭代器,std::evactor::iterator)[with _tpint;_Alloc=std::分配器;std::vector::迭代器=u gnu_cxx::u normal iter;typename std:vector:vector:vector\u base::pointer=int
矢量::
^
/usr/include/c++/4.8.5/bits/vector.tcc:146:5:注意:候选者需要2个参数,提供1个

> p>看来,你使用的是一个不完全支持C++ 11标准的旧编译器。 问题是函数
cbegin

auto i = answers.cbegin();

不能转换为在C++ 11标准之前的成员函数<代码>擦除< /代码>中使用的非常量迭代器。

在当前C++标准中,函数被声明为

iterator erase(const_iterator position);
你的代码应该可以编译

所以不是

auto i = answers.cbegin();
你需要使用

auto i = answers.begin();
但在任何情况下,最好用以下方式定义函数

#include <vector>
#include <algorithm>

std::vector<int> & eliminateZeroes( std::vector<int> &answers )
{
    answers.erase( std::remove( answers.begin(), answers.end(), 0 ), answers.end() );

    return answers;
}

我记得有一次libstdc++开始支持C++11,但一些容器缺少新的
erase(const_iterator)
重载。但我不认为
std::vector
有这个问题。@TomJB看起来您使用的是一个旧编译器。编写auto I=answers.begin();而不是auto I=answers.cbegin()“VladfromMoscow就是这样!!谢谢你。作为一个额外的奖励,我的函数第一次编译它……很好地改变了!BTW,”Tojb:不要写自己的循环,看看<代码> STD::移除< /Cord>算法和C++。这是非常有效的,因为元素最多只需要移动一次。@回答。不需要限定
std::begin
std::end
,它们将由ADL找到。@BenVoigt我认为这种方法是一种糟糕的编程风格。:)然后在本地范围内
使用std::begin;
,以便将来的读者理解它。但是禁用ADL比依赖它更糟糕。我能问一个问题吗关于这一点的估计?std::remove函数显然返回:“一个迭代器,指向最后一个未删除元素后面的元素。”。它将此返回给erase函数,该函数在迭代器指向的位置擦除该项。对我来说,这似乎是告诉erase函数删除我们不希望它删除的内容?我t工作得很好,所以我一定是误解了。@TomJB演示程序中使用的擦除函数使用了两个迭代器。第一个迭代器指向std::remove删除的第一个元素,第二个迭代器指向序列的结尾。也就是说,序列的尾部包含我们要擦除的元素。
#include <vector>
#include <algorithm>
#include <iterator>

std::vector<int> & eliminateZeroes( std::vector<int> &answers )
{
    answers.erase( std::remove( std::begin( answers ), std::end( answers ), 0 ), std::end( answers ) );

    return answers;
}