【问题标题】:Why can't C++ set iterators be cast to bool?为什么不能将 C++ 集合迭代器强制转换为 bool?
【发布时间】:2014-01-02 14:02:27
【问题描述】:

对于一个 STL 集,您似乎应该能够说:

if(s.find(x)) {
    //Something
}

相对

if(s.find(x) != s.end()) {
    //Something
}

此外,如果可以将 set-iterators 强制转换为 bool(如果内部指针不为 null,则为 true),您将能够做到。为什么 STL 集合迭代器没有这个简单的功能?这是故意遗漏的吗?

澄清:

另外,set 可能只有一个 set::contains(x) 方法,该方法直接返回一个 bool,但这似乎也没有实现。我知道这只是几个字符,但是在 s 是某个函数的返回值的情况下,这可能会令人沮丧,因为需要创建一个临时变量,即(假设 m 的类型为 map<int,set<int>>

const set<int>& s = m[i];
return s.find(x) != s.end();

相对

return m[i].contains(x);

return m[i].find(x);

编辑:

我没有意识到 count() 方法可以用作 contains()。投票结束,因为这个问题没有正确表达我真正应该问的问题:STL::set 有一个“包含”方法吗?

【问题讨论】:

  • 为什么你可以写s.find(x)?迭代器是位置,位置具有布尔状态似乎没有充分的理由。
  • 语义上,end 迭代器和null 是两个不同的概念
  • “如果内部指针不为空,则为真”——哇哦。谁说集合迭代器等于 end 当且仅当它的“内部指针为空”?并不是说它真的会影响您问题的主要部分,但这是对set 实施的毫无根据的假设。
  • 使用set::count
  • "可能只有一个 set::contains(x) 直接返回布尔值的方法,但这似乎也没有实现"。是的,正如本杰明刚才所说。该函数称为count,而不是contains

标签: c++ stl casting boolean set


【解决方案1】:

C++ 标准库中的迭代器不知道它们来自哪个容器,因此它们通常无法知道它们是否已经到达终点。这是经过深思熟虑的,以便让迭代器尽可能地轻量级——你不需要为你不使用的东西付费。 (迭代器泛化了指针的概念,指针就是迭代器。)

您始终可以将自己的自我感知迭代器构建为一对原生迭代器。

事实上,有些人认为这样的一对,或 range 是谈论集合的更自然的方式,并且有库以及库适配器来实现范围(例如升压范围)。

更新:迭代器比范围更底层,哪个概念是更好的解决方案是有争议的(尽管需要先定义问题)。迭代器更灵活一些;例如,如果您在迭代容器时对其进行变异,则必须“更新”所有范围对以接收新的“结束”值。 (或者以其他方式切换到完全“以范围为中心”的算法风格。)或者,您可以在迭代器中存储对容器的引用,并在每次需要时重新计算 end()。您已经可以看到有很多重要的细节,而 C++ 标准库只是决定不为您做出这些选择,而是只为您提供构建块来编写适合您的解决方案自己的问题最好。

【讨论】:

  • 这个可能就是答案,没有提出任何特殊情况。但问题不在于一般的迭代器,而在于set::iterator
  • @SteveJessop:当你改变容器时,很难保持范围不变量,所以迭代器可能是一个更通用的解决方案。
  • 当然,作为一个整体的迭代器尤其比set::iterator 更通用,我不能不同意这一点:-) 因为特别是设置突变不会使迭代器无效(除了删除的那个),我真的不明白突变会如何严重阻碍 set 实现实现 operator bool() (或更安全的东西),以使结束迭代器返回 false 而其他迭代器返回 true。
  • 似乎我可以将iterator(和const_iterator)的显式转换定义为bool——通过将它们与end()(或cend())进行比较) 的同一个容器——就在那里,在模板中......
猜你喜欢
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
相关资源
最近更新 更多