C++ 为什么我可以将两个不同容器的迭代器传递给sort?

C++ 为什么我可以将两个不同容器的迭代器传递给sort?,c++,C++,今天早些时候,我参加了一个在线编程比赛。有一个问题,我必须处理三个输入向量,其中一个需要排序。在一个简单的示例中,我的代码如下所示: vector <int> a; vector <int> b; . . . sort(begin(a), end(b)); 我唯一想看的部分是错误:函数需要一个有效的迭代器范围[\uu首先,\uu最后)。。我花了大约10分钟漫无目的地思考我做错了什么,虽然我看了几次排序部分,但没有注意到我愚蠢的错误。我不知道这是可能的(尽管我已经看过很多

今天早些时候,我参加了一个在线编程比赛。有一个问题,我必须处理三个输入向量,其中一个需要排序。在一个简单的示例中,我的代码如下所示:

vector <int> a;
vector <int> b;
.
.
.
sort(begin(a), end(b));
我唯一想看的部分是
错误:函数需要一个有效的迭代器范围[\uu首先,\uu最后)。
。我花了大约10分钟漫无目的地思考我做错了什么,虽然我看了几次排序部分,但没有注意到我愚蠢的错误。我不知道这是可能的(尽管我已经看过很多次函数定义)


<>我的问题是:为什么C++算法允许这样做,为什么C++委员会没有做过什么?为什么编译器不大声喊叫?它是故意用这种方式惩罚C++中犯愚蠢错误的人吗?C++中的所有其他东西都是这样的:


为什么C++算法允许这样做,为什么C++委员会没有做过什么? 因为它不是可以修复的。假设你有一个像
intarr[500]这样的数组
然后你想对它进行排序。你可以传递
arr
arr+500
作为排序的参数,但它们只是
int*
。它们不包含指向的地址以外的任何其他信息。
sort
无法检查这两个指针是否指向同一内存块


对于标准容器的迭代器也是如此。迭代器不提供访问它们来自的容器的方法,因此
sort
无法检查迭代器是否指向同一个对象。

为什么?因为否则,您将支付运行时检查编译时应检查的内容的费用:迭代器需要用它们来自的容器进行注释,
sort
需要检查


P> >你的有效抱怨应该针对C++库,而不是编译器,它不包括静态检查。静态代码分析器如PVS Studio通常会捕捉到这一点。静态代码分析器会捕获更多的新手错误,这会导致大量的浪费时间,所以我建议你装备。你自己也有一个。因为我最熟悉PVS工作室,我可以马上告诉你,它是.< /p>“为什么C++委员会没有做过什么?”如果你知道如何检测这个范围是无效的,你可以提交下一个C++标准的建议。这个可能性不限于委员会。个人,我不知道怎么做。Iterator与它所指向的容器非常相去甚远,如果两者都是VALL,则不能检查迭代器是否指向同一个容器。id等。此外,由于C++20有各种不同版本的算法,使用这些算法,您不会犯使用来自不同容器的迭代器的错误。编译器不会抱怨,因为类型是有效的。不确定您希望委员会做什么?也就是说,Microsoft的调试库断言迭代器必须来自同一个Container(我刚刚试过,得到:
Expression:范围内的向量迭代器来自不同的容器
),因此它似乎取决于您的库实现。我只想看一部分,但消息的其余部分由运行时提供,以帮助您解决问题。在本例中,“引用序列”行以迭代器引用的容器的地址结尾。由于这些地址不同,迭代器引用的不是同一个容器。永远不要忽略编译器或运行时消息提供的信息。@1201程序错误这就是我最终修复RTE的原因。我当时很匆忙,没有注意到fir中的地址部分在我修复它的时候,已经太晚了,无法提交任何有效的提交:(我以前在排序时从未遇到过这种错误,也不认为会发生这种情况。好吧,我们从错误中吸取教训,每天都能学到新的东西,对吧?谢谢。使用更好的变量名是让这些问题变得更明显的方法,另一个似乎是由竞争性编程传授的坏习惯哦,好吧,这让se.我对该语言的了解只够帮助我在代码中实现我对问题的想法,所以这对我来说是一件新鲜事。谢谢!我要指出的是,调试“配置”中的一些迭代器确实提供了一些这种功能。我刚刚测试过,MS的实现断言两个迭代器必须来自同一个容器。所以hey似乎将这些信息保存在迭代器中。但是我认为标准没有规定任何关于“调试功能”的要求。@Borgleader您是对的,有些实现会这样做,但这不是强制性的,里程数可能会有所不同。我省略了它,因为它甚至没有规定您进行一些有用的调试。@NathanOliver——还有那些ECK相当重。为了检测两个迭代器指向不同容器的元素,这些迭代器必须知道它们与哪个容器相关联。@PeteBecker你在考虑什么是重量级的?对于迭代器来说,存储一个指向它们来自的容器的指针并检查这些容器就很简单了我不会真的考虑重量级,但它绝对不是免费的。当本地测试代码时,如果排序必须检查它,我不会介意额外的开销,但这只是我个人的意见,因为我现在只为了解决问题而编写代码。如果STD::“那太好了。我确实安装了它,并编写了一些可能存在愚蠢错误的代码。乍看起来似乎很棒。谢谢!@LostArrow我很高兴你发现它很有用。这是一个漂亮的工具,许多初学者都不喜欢这些工具。我希望有人在材料强度和弹性理论的问题上也能做同样的事情。这些主题都很有趣。”特别愚蠢的错误
c:\programming\mingw\mingw 9.2.0\include\c++\9.2.0\bits\stl_algo.h:4825:
In function:
    void std::sort(_RAIter, _RAIter) [with _RAIter =
    __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*,
    std::__cxx1998::vector<int, std::allocator<int> > >,
    std::__debug::vector<int>, std::random_access_iterator_tag>]

Error: function requires a valid iterator range [__first, __last).

Objects involved in the operation:
    iterator "__first" @ 0x000000000023FDB0 {
      type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > >
(mutable iterator);
      state = dereferenceable (start-of-sequence);
      references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0000000000
23FD10
    }
    iterator "__last" @ 0x000000000023FD80 {
      type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > >
(mutable iterator);
      state = past-the-end;
      references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0000000000
23FCD0
    }

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.