【问题标题】:What does the C++ standard say about std::vector<int> v1,v2; std::distance(v1.begin(),v2.begin())?C++ 标准对 std::vector<int> v1,v2; 有什么看法?标准::距离(v1.begin(),v2.begin())?
【发布时间】:2015-06-21 16:18:41
【问题描述】:

我有这个代码

#include <vector>
#include <iostream>

int main(int argc, char* argv[])
{
   std::vector<int> v1,v2;
   std::cout << std::distance(v1.begin(),v2.begin());
   return 0;
}

它有一个错误,因为比较两个不同向量的迭代器没有意义。

我在第 815 页的 24.4.4 迭代器操作中查看了 N3376

template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);

要求:如果InputIterator满足随机访问迭代器的要求,则last应可从firstfirst访问 可从last 访问;否则,last 应该可以从 first.

现在我认为 Requires 没有满足。

在这种情况下,标准状态应该是什么?

【问题讨论】:

  • 如果标准不允许,很可能会导致未定义的行为,因为比较不同向量的迭代器有点不合逻辑
  • 一般来说,违反要求会产生未定义的行为。

标签: c++ iterator standards language-lawyer c++-standard-library


【解决方案1】:

[iterator.requirements.general]:

迭代器 j 从迭代器 i 被称为 reachable 当且仅 如果存在表达式++i 的有限应用序列 这使得i == j

问题是,一旦你将v1.begin()v1.size()-1 递增了几次,下一次递增操作会引发未定义的行为,因此无法从v1.begin() 到达v2.begin()。同样的论点使v1.begin() 无法从v2.begin() 访问。


如果您的问题是“如果违反 Requires 部分中的条件会发生什么?”,请查看 [res.on.required]:

违反函数的要求中指定的先决条件: 段落会导致未定义的行为,除非函数的 抛出: 段落指定当前提条件为时抛出异常 违反了。

【讨论】:

    【解决方案2】:

    std::distance 的某些实现中,第一个迭代器会递增,直到它到达第二个迭代器。计算迭代次数:

    unsigned int counts = 0;
    while (iter1 != iter2)
    {
      ++counts;
      ++iter1;
    }
    

    如果迭代器指向不同地址空间中的容器,循环很多不会终止。使用标准中的术语,第二个迭代器是不可达的。

    【讨论】:

      【解决方案3】:

      未满足requires,这意味着代码具有未定义的行为:任何事情都可能发生。

      【讨论】:

        【解决方案4】:

        在这种情况下将是未定义的行为。因为last 无法通过(可能重复地)递增firstfirst 访问。

        【讨论】:

          猜你喜欢
          • 2020-09-22
          • 2012-01-04
          • 2020-10-14
          • 2020-05-16
          • 2014-12-05
          • 1970-01-01
          相关资源
          最近更新 更多