集合范围构造函数的C++行为

C++ Behavior of set range constructor?

本文关键字:C++ 行为 构造函数 范围 集合      更新时间:2023-10-16

如果我有一个向量有很多重复元素,那么我就从这个向量构造一个集合。

#include <iostream>
#include <set>
#include <vector>
using namespace std;
int main ()
{
    vector<pair<int,int> > myvec={{1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3}};
    auto comp=[](pair<int,int> a,pair<int,int> b){return a.first<b.first;};
    set<pair<int,int>, decltype(comp)> myset(myvec.begin(),myvec.end(),comp);
    for (auto p:myset)
        cout<<p.second<<endl;
    return 0;
}

我的问题是,是否保证这些元素将按照向量的顺序插入到集合中,比如:

for (auto p:myvec)
myset.insert(p);

来自std::set:的MSVC实现

template<class _Iter>
void insert(_Iter _First, _Iter _Last)
{   // insert [_First, _Last)
    _DEBUG_RANGE(_First, _Last);
    for (; _First != _Last; ++_First)
        this->emplace(*_First);
}

此方法是从您使用的构造函数中调用的。因此,这是这种实施的保证。然而,我不确定这种行为是否得到了标准的保证。

IMO和为了可读性,我建议你在比较器中清楚地说明你想要的顺序,如下所示:

auto comp=[](std::pair<int,int> a,std::pair<int,int> b){
    if(a.first==b.first){
        return a.second<b.second;
    }
    return a.first<b.first;
};

"我有一个向量,它有很多重复元素"。通过这种假设,您只关心对的第一个组件,这在您的代码中是显而易见的。由于当时使用了"set","set"中的所有元素都将是唯一的,并且处于严格弱排序,即递增顺序(根据"comp"二进制谓词)。因此,如果向量中的元素(考虑到对的第一部分)已经按排序顺序排列,则可以保证元素将按向量中对的第一个部分的顺序插入集合中。

myset中的最终值={1,1}{2,1}{3,1}。