当需要修改元素时,什么是替代的类集数据结构?

时间:2011-09-23 15:49:01

标签: c++ data-structures set

STL集的设计使得无法修改集合中的元素(有充分的理由,请参阅stackoverflow)。然而,假设我有一个结构,其中只有一个成员充当关键。是否存在集合的替代数据结构。我真的想要集合的行为,除了无法修改非键的字段或成员。

4 个答案:

答案 0 :(得分:2)

我想到了一些可能性:

  1. 调整数据结构以使用std :: map
  2. 使用std :: set,但删除要更改的元素并将其替换为更新后的值。
  3. 设计并实施满足您要求的数据结构。
  4. 我认为前两个选项更可取;只有当您无法调整问题或现有的STL容器以满足您的需求时,才应使用鞋楦。

答案 1 :(得分:1)

将非密钥声明为mutable,然后您就可以修改它。

struct A
{
   KeyType key;
   mutable NonKeyType nonkey;
   //..
};

std::set<A> aset;
//...

const A & a = *aset.begin();
a.nonkey = newValue; //you can modify it even if the object `a` is const.

您必须确保nonkey确实是非关键的;它不得参与operator<比较功能。

答案 2 :(得分:1)

考虑到std :: map而不是std :: set,可能是重新设计的时候了。

而不是

struct A
{
   K key;
   V val;
};

set<A> a;

考虑

std::map<K,V> m;
然后你可以做

m[k] = v;

答案 3 :(得分:0)

无法强制执行排序谓词中使用的类的成员不会被修改。对排序谓词中使用的成员的修改可能会破坏该集合。

欺骗编译器让你使用带有可变成员的集合的简单方法是将成员标记为可变:

 class Foo
 {
     std::string myVal1;
     mutable std::string myVal2;
 public:
     bool operator<(const Foo& rhs)const {
         return myVal1 < rhs.myVal;
     }
 };

然后,您必须手动确保Foo::operator<()在比较中始终不使用myVal2。这是可能的,但是坏主意(tm)。您可以使用大量注释标记此特定运算符,但不能自动将此注释复制到所有自定义比较函数中(std::set<>接受此作为第二个参数)。

实现目标的真正方法是使用std::map<>。将“key”部分放在键中,将“value”部分放在值中。