设置插入如何在以下情况下工作?

时间:2016-10-18 05:32:25

标签: c++ stl set

以下结构:

struct SomeStructure {
      uint64_t value;
      uint64_t data;
};

bool operator > (const SomeStructure& v1, const SomeStructure& v2) {
       return (v1.value > v2.value);
}
bool operator < (const SomeStructure& v1, const SomeStructure& v2) {
       return (v1.value < v2.value);
}
bool operator == (const SomeStructure& v1, const SomeStructure& v2) {
       return (v1.value == v2.value);
}

用于类似以下的代码:

SomeStructure st1, st2;
st1.value = st2.value = 10;  // has the same 'value'
st1.data = 20;    // but is assigned a different number for the 'data'. 
st2.data = 40;

std::set<SomeStructure> TheSet;
TheSet.insert(st1);
TheSet.insert(st2);

st2之后插入st1会替换集合中存在的元素的值吗?

在上面的示例中,由于运算符><重载仅依赖于成员SomeStructure::value,因此st2st1都被视为在将它们插入TheSet时保持平等。但是SomeStructure::data的值对于这两个对象都是不同的。那么它会替换TheSet中的现有元素,还是如果元素已经存在则会忽略插入操作?

有没有办法明确执行这两种行为?

此行为会随编译器和平台而改变吗?

修改1:

我刚用g ++编译器测试了这个(启用了c ++ 11)。它不会取代。那么有没有办法明确强制执行此操作来替换现有元素?

编辑2:

实际上,没有标准的方法来强制执行&#34;这种行为,但可以使用简单的 hack through 来完成。虽然不建议使用此方法,但请在此处介绍:

必须使用此方法代替std :: set

中的成员函数插入
template <typename T>
void insert_replace(std::set <T>& theSet, const T& toInsert) {
      auto it = theSet.find(toInsert);
      if(it != theSet.end())
         *((T*)&(*it)) = toInsert;
      else
          theSet.insert(toInsert);
}

以上代码必须替换为:

int main() {

    SomeStructure st1, st2;
    st1.value = st2.value = 10;  // has the same 'value'
    st1.data = 20;    // but is assigned a different number for the 'data'.
    st2.data = 40;


    std::set<SomeStructure> TheSet;

    insert_replace (TheSet, st1);
    insert_replace (TheSet, st2);


    for(auto ii : TheSet) {
        std::cout << ii.data;
    }
    return (0);
}

此方法适用于我的编译器,提供输出:40,而不是20。但我认为人们可能会说这不是推荐的方法,因为行*((T*)&(*it)) = toInsert;使编译器误以为迭代器it不是常数(但实际上是)。我相信这是我们通过替换强制插入std::set的唯一方法。在我的代码中使用此方法是否可以?或者它会在将来引起问题(即使我记录了它)?

1 个答案:

答案 0 :(得分:1)

来自documentation

  

插入操作检查每个插入的元素是否等同于容器中已有的元素,如果是,则不插入元素

所以TheSet.insert(st2);不会插入任何内容,因为st2等于st1,它已经在集合中。

如果您希望能够同时插入它们,则需要更改比较函数,以便它们同时测试valuedata,或使用std::multiset,这允许重复输入