1
    #include <bits/stdc++.h>
    #define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
    #define SZ(s) int(s.size())
    using namespace std;
    typedef long long ll;
    int main()
    {
        FIN;
        set<ll>s;
        ll N, M;
        cin >> N >> M;
        ll x;
        for(ll i = 0; i < N+M; i++)
        {
            cin >> x;
            if(x==-1)
            {
                auto x = *s.rbegin();
                cout<<x<<'\n';
//-------------------------------------------------------------------------------------------------
                s.erase( --s.end() ); // --s.end() when replaced with s.rbegin(), gives an error
//------------------------------------------------------------------------------------------------
            }
            else
            {
                s.insert( x );
            }
        }
        
    }

在水平线之间的代码中,我试图从集合中删除最后一个元素。

当我写s.erase( s.rbegin( ) ) 而不是s.erase( --s.end( ) )时,它给了我一个编译错误说:

 **error: no matching function for call to ‘std::set<long long int>::erase(std::set<long long int>::reverse_iterator)’
   20 |    s.erase( s.rbegin() );**

不是 s.rbegin() 和 --s.end() 指向同一个元素吗?

4

2 回答 2

3

std::set::rbegin 返回一个reverse_iterator,它在技术上指向同一事物,但该集合没有接收 reverse_iterator 作为参数的擦除方法。

于 2020-07-16T17:49:54.777 回答
2

reverse_iterator不与iterator. an 的逻辑地址和物理地址iterator是相同的,但是对于 来说reverse_iterator,逻辑地址和物理地址不同。例如:s.end()并且s.rbegin()具有相同的物理地址但*s.end()会给你一个错误但*s.rbegin()会给你容器的最后一个值s

下面的代码将使事情变得清晰:

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> S{ 1, 2, 3 };
    
    set<int>::iterator itr = S.find(2);
    cout << *itr << endl;

    set<int>::reverse_iterator r_itr(itr);
    cout << *r_itr << endl;

    cout << itr._Ptr << ' ' << r_itr.base()._Ptr << endl;

    //S.erase(r_itr);       // ERROR!
    S.erase(r_itr.base());

    for (int e : S)
        cout << e << ' ';
}

在我的机器上,它产生了以下输出:

2
1
00F85DA8 00F85DA8
1 3
于 2020-07-16T18:30:34.600 回答