检测插入std :: set的坏项

时间:2011-09-23 08:27:21

标签: c++ algorithm stl

假设我的集合中有自定义类型,并且只有在某些属性上所有项目具有相同值时才设置/排序...如果插入了具有不同值的项目,则模型被搞砸了想保护这个。

我想也许比较函数可能是我们可以测试它(作为断言或异常)的地方,以标记问题和/或防止项目被插入。例如,在TypeName上,如果重要属性不相等,则运算符<()始终返回false。

这是否合理?

4 个答案:

答案 0 :(得分:6)

我想把它放在比较器中可能会有问题,因为当你要调用它时你没有得到任何保证。也许一些神话般的实现在项目数量较少时将项目存储在列表中,并且直到稍后才调用比较器?

可能最简单的方法是将std::set包装在执行这些断言的保护性外部类中。

class MySet {
  private:
     std::set<myFunkyType> myType;

  public:
     void insert(myFunkyType type) {
        assert(!type.isFunky(), "funk violation");
        // and so on
     }

     // all other members other than insertion or mutation just delegate to the
     // underlying set

}

答案 1 :(得分:0)

如果您的std::set是自定义类的实现细节,则应该由您的类的公共成员函数决定,以确保您的集合中未插入无效元素。否则,如果您需要一个数据结构来传递对象集合而不是使用std::map,请为您的类提供密钥生成函数并将错误检测代码放在那里。

请记住,作为地图键的集合元素在排序方面应该是不可变的;基于可变状态的排序气味不好。

答案 2 :(得分:0)

operator<这个想法听起来有点可疑。这仅仅意味着这些元素最后排序。对于所有y,x是iff x<y==false的最大元素,并且x<x==false必须始终保持。但如果这对你来说是可以接受的,那就没关系。

答案 3 :(得分:0)

当你在op&lt;你发现你不能建立一个严格的弱序,唯一合理的是抛出异常。任何类型的插入,或op的可能的其他返回&lt;可能会破坏集合的内部约束。

包装是恕我直言并不是必需的,因为包装的insert()的行为可能是相同的(即抛出异常)。

唯一可能使包装更具吸引力的是,您的标准库实现是否足以能够应对投掷比较器的任何不确定性。我怀疑许多标准库实现对该操作的异常安全性很强。