When calling std::sort() on a std::array:
#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));
}
Both gcc and clang return an error on the sort on the std::array -- clang says 
error: use of undeclared identifier 'sort'; did you mean 'std::sort'?
Changing to std::sort(begin(foo2), end(foo2)) fixes the problem.
MSVC compiles the code above as written.
Why the difference in treatment between std::vector and std::array; and which compiler is correct?
This is comes down to the type that begin and end result to and how that works with Argument Dependent Lookup.
In
sort(begin(foo), end(foo));
you get
sort(std::vector<int>::iterator, std::vector<int>::iterator)
and since std::vector<int>::iterator is a member of std ADL finds sort in std and the call succeeds.
With
sort(begin(foo2), end(foo2));
You get
sort(int*, int*)
and because int* is not a member of std, ADL will not look into std and you can't find std::sort.
This works in MSVC because
sort(begin(foo2), end(foo2));
becomes
sort(std::_Array_iterator, std::_Array_iterator)
and since std::_Array_iterator is part of std ADL finds sort.  
Both compilers are correct with this behavior.  std::vector and std::array don't have any requirement on what type is used for the iterator except that it satisfies the LegacyRandomAccessIterator requirement and in C++ 17 for std::array that the type also be a LiteralType and in C++20 that it be a ConstexprIterator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With