C++ 非限定排序()--为什么它在std::vector上使用而不是在std::array上使用时进行编译,以及哪个编译器是正确的?

C++ 非限定排序()--为什么它在std::vector上使用而不是在std::array上使用时进行编译,以及哪个编译器是正确的?,c++,c++17,C++,C++17,在std::array上调用std::sort()时: #include <vector> #include <array> #include <algorithm> int main() { std::vector<int> foo{4, 1, 2, 3}; sort(begin(foo), end(foo)); std::array<int, 4> foo2{4, 1, 2, 3}; sort(b

std::array
上调用
std::sort()时:

#include <vector>
#include <array>
#include <algorithm>

int main() {
    std::vector<int> foo{4, 1, 2, 3};
    sort(begin(foo), end(foo));

    std::array<int, 4> foo2{4, 1, 2, 3};
    sort(begin(foo2), end(foo2));
}
#包括
#包括
#包括
int main(){
std::矢量foo{4,1,2,3};
排序(开始(foo),结束(foo));
std::数组foo2{4,1,2,3};
排序(开始(foo2),结束(foo2));
}
gcc和clang都在
std::array
上的排序上返回一个错误——clang说

错误:使用未声明的标识符“sort”;你是说“性病::分类”吗

更改为
std::sort(开始(foo2),结束(foo2))
修复了该问题

MSVC编译上面写的代码


为什么
std::vector
std::array
在治疗上存在差异;哪种编译器是正确的?

这取决于
开始
结束
结果的类型,以及它们是如何工作的

你得到

sort(std::vector<int>::iterator, std::vector<int>::iterator)
你得到

sort(int*, int*)
由于
int*
不是
std
的成员,ADL不会查看
std
,您也无法找到
std::sort

这在MSVC中有效,因为

sort(begin(foo2), end(foo2));
变成

sort(std::_Array_iterator, std::_Array_iterator)
由于
std::_Array\u iterator
std
ADL查找
sort
的一部分


这两个编译器都正确处理此行为<代码> >代码:>代码> STD::数组< < /代码>,除了满足它的要求之外,没有任何要求,除了满足C++和17的代码:“代码> STD::数组< /代码>,类型也是A,C++ 20中它是

代码>排序(…<代码> >代码> STD::排序(…<代码)>我想ADL。(依赖于参数的查找)正是让您感到困惑的地方。这或演绎指导着您。在任何情况下,总是要限定您调用的函数。可能是因为MSVC库具有某种特殊的
std::sort
,这导致了(就像您已经为
std::begin
std::end
)?@Someprogrammerdude很简单,VC++的stdlib中的所有容器都使用
命名空间std
中定义的类类型迭代器,即使在简单的指针类型可以工作的地方也是如此。我相信这是为了插入调试构建检查来检测溢出和其他常见错误。我想问题是MSVC的行为是否符合要求,即。
std::array
迭代器必须是
int*
还是可以是类类型?类似地,对于
std::vector
来说,这与迭代器是否必须是ADL工作的类类型,或者它是否也可以是
int*
有关。@walnut它可以是实现想要的任何类型e、 它可能是一个
std::迭代器
,或者只是一个指针。我还想知道为什么在这个库实现中,他们选择对
std::array
使用
int*
,而不是对
std::vector
使用
int::vector
的迭代器类型是未指定的,这意味着这个实现允许将它们定义为原始指针(代码不会编译)或类类型包装器(仅当类类型具有
std
作为ADL关联命名空间时,代码才会编译)。其中ADL使用别名失败,而ADL使用嵌套类成功。在这里和我之前的测试中,
std::vector::iterator
都是别名。
sort(begin(foo2), end(foo2));
sort(std::_Array_iterator, std::_Array_iterator)