C++ 是什么使得这些迭代器比较行为未定义?

C++ 是什么使得这些迭代器比较行为未定义?,c++,undefined-behavior,C++,Undefined Behavior,在这方面,它说: 将值初始化迭代器与迭代器进行比较的结果 具有非奇异值的函数是未定义的 vector<int> v = {1,2,3}; auto ni = vector<int>::iterator(); auto nd = vector<double>::iterator(); ni == ni; // True. nd != nd; // False. v.begin() == ni; // Undefined behavior (likely fals

在这方面,它说:

将值初始化迭代器与迭代器进行比较的结果 具有非奇异值的函数是未定义的

vector<int> v = {1,2,3};
auto ni = vector<int>::iterator();
auto nd = vector<double>::iterator();
ni == ni; // True.
nd != nd; // False.
v.begin() == ni; // Undefined behavior (likely false in practice).
v.end() == ni; // Undefined behavior (likely false in practice).
ni == nd; // Won’t compile.
向量v={1,2,3}; auto ni=向量::迭代器(); auto nd=向量::迭代器(); ni==ni;//对。 nd!=nd;//错。 v、 begin()==ni;//未定义的行为(在实践中可能是错误的)。 v、 end()==ni;//未定义的行为(在实践中可能是错误的)。 ni==nd;//不会编译。
  • 非奇异值是什么意思
  • 为什么这是未定义的行为

    • 你问了两个截然不同的问题。你关于单数和非单数的问题,所以我将忽略这个问题,只关注一个不重复的问题

      有些容器可能使用特殊的迭代器值,这些值看起来与默认构造的迭代器值完全相同。例如,对于
      end()
      返回的迭代器,没有有效指针值的迭代器可以使用其迭代器类型的空指针等价物来表示这些值

      对于这些情况,要求比较结果评估为
      true
      ,这意味着即使将来为这些迭代器值设计了更好的方法,实现也不会改变

      对于这些情况,需要将比较计算为
      false
      ,这意味着实现将被迫更改

      未定义比较为实现提供了可能需要的自由度

      Xarn在评论中指出,让比较给出一个未指明的结果可能是更好的选择(要么
      false
      要么
      true
      ,但没有其他选择)。这本来是一个有效的选择,但在提出建议时的行为已经是不允许与来自不同容器的迭代器进行比较(未定义的行为,而不是未指定的结果),而且据我所知,这项建议只是试图不改变任何不必要的内容,所以保持原样


      使其未定义而非未指定的一个有效理由是,某些实现可能希望提供特殊的调试迭代器,其中无效比较(几乎肯定是程序员错误)会使用有用的消息中止程序。

      Hm。。。我认为默认的初始化迭代器指向未定义的位置,就像默认的初始化原始指针一样,在设置之前不应该使用它。将迭代器比较到不同容器的语义并不是为了效率而定义的,任何容器都可以等于没有容器吗?不,所以这个定义并不令人惊讶,而且可能是提高效率所必需的。我非常希望下一个标准,当他们想要集成范围以及结束迭代器类型时。会更快,因为不再需要有神奇值的愚蠢的末端迭代器。要求比较为真在逻辑上毫无意义,因为很多原因,我不会全部列出。另一方面,将这种比较弄错将是一个完全合理的选择。因为非奇异值不指向任何东西,所以可以合理地说它不等于任何东西,类似于浮点的NaN。而且实施起来也非常合理。我需要看一个容器的具体例子,为了让你相信你所说的,强迫这个比较为假。我认为标准没有定义,因为它只是没有定义。@Nir就像我说的,当前的实现可能使用这样的迭代器值。有可能以不同的方式实现它们的事实并没有改变它的成本(时间和兼容性的破坏)。在这种情况下,未指定的不是比未定义的要好得多吗?仍然不会有任何东西强制执行非性能实现,但您也不会玩弄可能会爆炸的代码。@Xarn这是一个好问题,我现在在回答中已经提到了这一点。